2022新卒がWebRTCとメッセージングのSDKでビデオ通話＋チャットを作ってみた

## はじめに

RTCによるビデオ通話機能と、リアルタイムチャットを行うそれぞれのサンプルは各所にあります。
そこで今回はRTCSDK for web v4.15.0 とRTMSDK for web v1.5.1を一つのスクリプトにまとめて動かします。
目標としては、RTCSDKによるbasicVideoCallに、並行してRTMのchannelMessgeによるチャットの送受信が出来る機能を追加します。
完成物は以下になります。

https://github.com/fu-jimoto/RTC-RTM

![スクリーンショット(rtc+rtm).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/7900c32f-8006-4263-844d-4d8435c324bd.png)

## 開発環境
Chrome 107.0.5304.121
AgoraRTCSDK for Web 4.15.0
AgoraRTMSDK for Web 1.5.1

## 実装

### RTCの導入

[こちら](https://docs.agora.io/en/sdks?platform=web)から、Video SDKをダウンロードしましょう。
実行してビデオ通話が出来る事が確認できたらRTCSDKの導入は完了です。

webSDK4.xの導入のより詳しい内容については[こちら](https://qiita.com/v-cube/items/dd30a977b68855ceeb64)

### RTMの導入

[こちら](https://docs.agora.io/en/sdks?platform=web)からSignaling SDK(旧real-time-messaging SDK)の最新版をダウンロードしましょう。
解凍したら、Agora_RTM_SDK_for_Web/libs にある「agora-rtm-sdk-{バージョン名}.js」を、先ほどのwebSDKと同じ階層に置きます。

これで、同一スクリプト内でRTCとRTMの実装を行う準備ができました。


ここからはチャットの為の機構をそれぞれ追記していきます。

まずはRTMSDKを読み込ませます。

```index.html
<script src="./agora-rtm-sdk-1.5.1.js"></script>
```

次に、チャットのテキストエリアとチャットの表示欄を作成します。
formの閉じタグの直下からscriptタグのある箇所の上までを以下のコードに置き換えます。

```index.html
<hr>
<div class="row">
      <div class="col-sm-">
        <div class="input-group mb-2 w-50">
          <div class="input-group-prepend">
            <span class="input-group-text">Message</span>
          </div>
          <textarea type="text" class="form-control" id="message" ></textarea>
        </div>

        <div class="button-group mb-2">
          <button id="send" class="btn btn-info btn-sm">SEND</button>
        </div>

        <div class="video-group">  
          <p id="local-player-name" class="player-name"></p>
          <div id="local-player" class="player"></div>
          <div id="remote-playerlist"></div>
        </div>
      </div>
      <div class="col-sm offset-sm-1">
        <div class="row">
          <div class="col-lg-3">
            <div id="name"></div>
          </div>
          <div class="col-lg-9">
            <div id="text"></div>
          </div>
        </div>
      </div>
    </div>
```

htmlの記述は以上です。
ここからindex.jsの追記です。

まずはrtm用の変数を作成します。

```index.js
var rtm = {
  client: null,
  channel: null
}
```

また必須ではないですが、これからRTMClientのjoin周りの処理を記述する関数 joinRTM() を作成する為、差別化として元々のRTCのjoin用の関数を joinRTC() という名称に変更しておきます。
呼び出し時の記述も忘れずに変更します。

その後通常のRTMの記述と同様に、createInstanceからlogin、joinを行います。

```index.js
function joinRtm() {
  //Create an Instance and Channel
  rtm.client = AgoraRTM.createInstance(options.appid);
  rtm.channel = rtm.client.createChannel(options.channel);

  //Set a listener to the connection state change
  rtm.client.on("ConnectionStateChange", function (newState, reason) {
    console.log("on connection state changed to " + newState + " reason:" + reason);
  });
  //Log in the Agora RTM system
    rtm.client.login({uid: "" + options.uid}).then(function(){
    console.log("AgoraRTM client login success");
    rtm.channel.join().then(function(){
      console.log("AgoraRTM client join success");
    }).catch(function (err){
      console.log("AgoraRTM client join failure, ", err);
    });
  }).catch(function(err){
    console.log("AgoraRTM client login failure, ", err);
  });
}
```

joinボタンを押下した際に、joinRTC() と同時に実行します。
await joinRTC(); 
の直下で呼び出します。

```index.js
joinRtm(); //この行を追記
```

送受信したチャットをチャット欄に追記する処理を記述します。

```index.js
function addMessage(name, message){
  const nameView = $('<div/>', {
    text: name + ': '
  })
  const messageView = $('<div/>', {
    text: message
  })
  $('#name').append(nameView);
  $('#text').append(messageView);
}
```

メッセージを送信した際の処理を記述します。

```index.js
$("#send").click(function (e) {
  console.log("request");
  sendChannelMessage();
})

function sendChannelMessage(){
  const message = $("#message").val();
  rtm.channel.sendMessage({text:message}).then(function(){
    console.log("AgoraRTM client succeed in sending channel message: " + message);
    addMessage("あなた", message);
    $("#message").val("");
  }).catch(function(err){
    console.log("AgoraRTM client failed to sending role" + err);
  });
}
```

メッセージを受信した際の処理を記述します。

```index.js
function receiveChannelMessage(){
  rtm.channel.on("ChannelMessage", function (sentMessage, senderId) {
    console.log("AgoraRTM client got message: " + JSON.stringify(sentMessage) + " from " + senderId);
    addMessage(senderId, sentMessage.text);
  });
}
```

joinRTM() 内から呼び出します。

```index.js
rtm.channel.join().then(function(){
  console.log("AgoraRTM client join success");
  receiveChannelMessage(); //この行を追記
```

最後 leave する際に、rtmもログアウトさせます。
leave() に以下を追記します。

```index.js
rtm.client.logout().then(() => {
  console.log("AgoraRTM client logout success");
})
```

以上で、ビデオ通話を行いながらRTMによるchannelMessageの送受信をする機能が実装できました。

## 関連リンク

- [Video SDK v4.15.0 API Reference for Web](https://api-ref.agora.io/en/video-sdk/web/4.x/index.html)
- [Signaling (previously RTM) SDK v1.5.0 API Reference for Web](https://api-ref.agora.io/en/signaling-sdk/web/1.x/index.html)

## 最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=f712953155ddadcf0177)
[<img width="912" alt="Agoraの詳細はこちら" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5865441c-9d31-c702-3698-3aeb84927f28.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=f712953155ddadcf0177)