Tech Sketch Bucket of Technical Chips by TIS Inc.

WebRTC(PeerJS)で遠隔作業支援システムを作る(4)

Pocket

WebRTCを用いた遠隔作業支援システムを作ります。 前回 はCoffeeScriptで記述されたモジュールの全体構成と、PeerJS & MediaStreamの初期化処理について説明しました。今回はWebRTCの肝となるシグナリング処理からスマートグラスのカメラ映像をリアルタイムで監視端末に表示する部分までを解説します。

シグナリングの処理フロー

前回 まででPeerJSの初期化が完了し、peerjs-serverとのWebSocket接続が確立されてユニークIDが通知されました。またMediaStreamも取得してあり、デバイス自身のカメラやマイクとの接続が確立しています。

では次に、スマートグラスと監視端末をP2P接続するシグナリングの処理フローとPeerJSを用いた実装をステップを追って確認しましょう。以下3つのステップで処理が行われます。

  1. スマートグラスのPeerIDを監視端末に入力し「CALL」
  2. MediaConnectionの確立
  3. DataConnectionの確立

1. スマートグラスのPeerIDを監視端末に入力し「CALL」

PeerJSを用いて他のPeerとP2P接続を行う場合、接続先PeerのユニークIDを指定しなければなりません。今回はシンプルに、スマートグラスの接続待ち画面(device画面②(下図左))に表示したユニークID(下図であれば f9uyrhv2lzwljtt9 )を、監視端末(monitor画面②(下図右))の入力フォームに転記する形で実装しました。

device_02.pngmonitor_02.png

ただ今回の実装のような手入力は面倒ですしミスも発生しますので、イケてるGUIとは言えません。
現在は静的コンテンツの配信しか行なっていないexpressにロジックを追加し、監視端末のブラウザ上に接続可能なスマートグラスの名前を一覧表示してリストからペアリング先のスマートグラスを選択するようなGUIを作ったほうが良いでしょう。

W3CSystem Applications WG では、Bluetoothのようなデバイスを直接操作する低レベルなAPIの仕様策定が進められており、Firefox OS向けにWebBluetooth APIなども実装され始めています。
将来このようなAPIがブラウザからも利用できるようになれば、近くに置いたスマートグラスを自動的にペアリングするようなUIが作れるかもしれません。

監視端末の「CALL」ボタンをクリックすると、登録されたクリックイベントが発生しシグナリング処理が開始されます。

2. MediaConnectionの確立

MonitorClassのmakeCallメソッドでは、MediaConnectionの接続要求とDataConnectionの接続要求を一挙に実施します。
まずはMediaConnectionの接続処理から追ってみましょう。
MediaConnection :WebRTCのRTCPeerConnectionによって交換されるMediaStreamをラップしたオブジェクト

WebRTC_08.png

監視端末:MediaConnectionの接続要求を送信

最初に @peer.call() を呼び出すことで、監視端末側からスマートグラスに向けてMediaConnectionの接続要求を出します(Offer送信)。この際、接続済みの監視端末のMediaStreamを引数に渡します。
監視端末側ではこの段階でMediaConnectionオブジェクトが取得できますが、P2P接続が確立していないため、まだ利用できません。

BaseClassに実装されたconnectメソッドには、MediaConnectionの接続が確立した際のイベントハンドラと接続が閉じられた場合のイベントハンドラが記述されています(後述)。

スマートグラス:MediaConnectionの接続要求の受信イベント発生

スマートグラスがシグナリングサーバに中継された接続要求を受信すると、 @peer.on('call', callback) イベントが発生し、設定したcallback関数が呼び出されます。
下記のように、接続要求受信時には、接続済みのスマートグラスのMediaStreamを引数に接続受託を返信(Answer送信)することになります。

監視端末・スマートグラス:MediaConnectionのイベント処理

MediaConnectionに設定できるイベントハンドラにはいくつかありますが、重要なのは次の二つです。

  • MediaConnection.on('stream', callback)
    MediaConnectionの接続が確立し、接続相手先のMediaStreamが利用可能となった際に呼び出される。
  • MediaConnection.on('close', callback)
    自分もしくは接続相手先が、MediaConnectionを切断した際に呼び出される。
    (MediaConnectionの切断を検知するまでは数秒のタイムラグがある)

MediaConnection.on('stream', callback) イベントの発生時には、取得した接続相手のMediaStreamをvideoタグのsrcに接続し、通常作業画面を表示します。
また MediaConnection.on('close', callback) イベントの発生時には、自分自身のマイクをOFFにした後に切断されたMediaConnectionをcloseし、接続待ち画面へ戻ります。

3. DataConnectionの確立

MediaConnection確立とは並列に、DataConnectionの確立も行います。DataConnectionの接続処理を追ってみましょう。
DataConnection :WebRTCのRTCPeerConnection上に構築されるRTCDataChannelをラップしたオブジェクト

WebRTC_09.png

監視端末:DataConnectionの接続要求を送信

DataConnectionの場合、監視端末が @peer.connect() を呼び出すことで、P2P接続の確立まで処理が進みます。MediaConnection接続時のように、「Offer受信時にAnswerを送信する処理」をスマートデバイス側に明示的に実装する必要はありません。

@peer.connect() を呼び出す際に、オプションとして {reliable:true} を渡してください。 第一回 でも解説しましたが、RTCDataChannelはSCTPを用いておりTCPのような信頼性のあるデータ転送を行わせることができます。 {reliable:true} を設定することで、SCTPに信頼性の有るモードが設定されます。

もしブラウザの実装が信頼性の有るモードをサポートしていない場合、PeerJSは自力で再送や順序制御を行って信頼性のあるデータ通信を実現します(が、遅くなります)。

※残念ながら現時点のPeerJSの実装を確認する限り、特定環境下のFirefox間でなければブラウザ実装の信頼性の有るモードはまともに動かないようです。

監視端末:DataConnectionのイベント処理

DataConnectionの接続が確立しDataConnectionが利用可能となった際に、 DataConnection.on('open', callback) イベントが発生します。またDataConnectionの接続が切断されると、 DataConnection.on('close', callback) イベントが発生します。

データ転送を行う際に必要になるため、 DataConnection.on('open', callback) イベント発生時にDataConnectionオブジェクトをインスタンス変数に格納しましょう。
また DataConnection.on('close', callback) イベント発生時には、切断されたDataConnectionをcloseしておきます。

スマートグラス:DataConnectionのイベント処理

P2P接続が確立すると、 @peer.on('connection', callback) イベントが発生しcallback関数へDataConnectionオブジェクトが渡されます。このDataConnectionオブジェクトに対し、以下のイベントハンドラを設定します。

  • DataConnection.on('open', callback) イベント: DataConnectionが利用可能となった際に発生
  • DataConnection.on('data', callback) イベント:接続相手先からデータを受信した際に発生
  • DataConnection.on('close', callback) イベント:DataConnectionの接続が切断された際に発生

DataConnectionが利用可能となった際とDataConnectionの接続が切断された際の処理は、監視端末での実装と同じです。
接続相手先からデータを受信した際には、受信したデータの種別を確認することで処理を分岐させます。
(データ受信処理の詳細は、次回解説します)

スマートグラスのカメラ映像をリアルタイムで監視端末に表示する

お疲れ様でした。ここまででスマートグラスと監視端末のペアリングが完了し、遠隔作業支援の通常作業に入ります。

WebRTC_10.png

通常作業画面(device画面③(下図左)とmonitor画面③(下図右))では、スマートグラスには監視端末へカメラ映像を転送しているメッセージが表示され、監視端末ではスマートグラスのカメラ映像がリアルタイムに表示されます。

device_03.pngmonitor_03.png

次回は

今回ようやくWebRTCを用いたカメラ映像のリアルタイム表示まで実装できました。最終回の次回は、DataConnectionを用いたテキストメッセージや画像の転送処理、及び接続終了処理について解説し、遠隔作業支援システムとして完成させます。

エンジニア採用中!私たちと一緒に働いてみませんか?