socket ioでビデオ通話+ユーザー名表示

# Zoomにあるようなビデオ映像に名前を入れて欲しい…
以前に作成した[socket.io にセッション情報を渡す](https://qiita.com/4201tosiyuki/items/80ee553ac42eeb323859)と[Express+MySQLでログインする](https://qiita.com/4201tosiyuki/items/7ece29ed48b49efcbe59)の続編です。

改めて、このプログラムを書いた経緯です。

1. 自社ネットワーク内でビデオ通話をしたいという相談をうける
2. [hidden.in](https://qiita.com/ukiuni@github/items/a1372fac50a4ece1d5e8)を見つける
3. これは便利だと感動し、セットアップする
4. ユーザー名（支店名）を表示して欲しいと相談をうける
5. Node.jsを勉強する

このような経緯で今に至っております。

冒頭に紹介した記事で、MySQLにユーザー情報を保存しておき、passportモジュールを読み込み、ログイン判定をする。というところまでが出来ている想定で話を進めます。

### では、実装方法です！
編集するファイルは

* index.js
* static/js/index.js
* static/css/app.css
* views/screen.ejs(前回説明不足でしたが、元からあるstatic/screen.htmlをejsファイルに変更しています。ディレクトリもviewsフォルダを作成しています。）

#### プログラムの流れ（イメージ）

1. ログインしているユーザーがemit('join')する
2. サーバーサイドでon('join')された時emit('joined')でユーザー名とIDを渡す
3. サーバーサイドでemit('otherjoined')する
3. ２に対してクライアントでユーザー名を保持する
4. on('otherjoined')した時にmyNameSend関数を呼び出し、自分の名前とIDをemitする
5. サーバーサイドでon('mynamesend')された時にemit('othernamesend')で値を送る
6. クライアントサイドでon('othernamesend')を受け取った時にユーザー名を表示させる


```javascript:index.js
//中略
//サーバーサイド
//プログラムの流れ2,3

socket.on('join', function (req) {
    io.to(socket.id).emit("joined", { id: socket.id,name:socket.request.session.passport.user });
    socket.broadcast.to(socket.room).json.emit("otherJoined", { id: socket.id});

}

```
ここでは、joinしたユーザーに対して、joinedを送る+ルームにいるメンバーに対して、他のユーザーがルームに入ったことを知らせています。

```javascript:static/js/index.js
//中略
//クライアントサイド
//プログラムの流れ4,5
socket.on('joined', function (event) {
        joinedToRoom = true;
        // socket.idが入っている
        selfId = event.id;
        //usernameが入っている
        myName = event.name;
      }).on('otherJoined', function (event) {
        sendOffer(event.id);
        myNameSend(selfId,myName);
    })

//myNameSend関数
function myNameSend(myId,myName){
   socket.emit('mynamesend',{id:myId,name:myName});   
}

```

見ての通りです

```javascript:index.js
//中略
//サーバーサイド
//プログラムの流れ6
socket.on('mynamesend',function(id,name){
    socket.broadcast.to(socket.room).emit('othernamesend',{id,name});
  });

```

myNameSend関数で送られてきた値をブロードキャストしてルームに所属するユーザーに送っています。

```javascript:static/js/index.js
//中略
//クライアントサイド
//プログラムの流れ7
.on('othernamesend',function(event){
        otherNameCreate(event);        
    })

function otherNameCreate(otherconf){
     if(otherconf.id.name != myName){
    var otherId = 'area_' + otherconf.id.id;
    var otherArea = document.getElementById(otherId);
    if(!otherArea){
        otherArea = document.createElement('div');
        otherArea.className = 'remoteArea';
        otherArea.id = otherId;
        document.getElementById('video_wrap').appendChild(otherArea);
        remoteName = document.createElement('span');
        remoteName.className = 'remoteName';
        remoteName.textContent = otherconf.id.name;
        otherArea.appendChild(remoteName);
    }
    }else{
    console.log('名前が一緒');
    return;
    }
}

```

名前表示の制限として自分と違う名前なら表示させるようにしています。

area_ + socket.idというように一意なエリアを作成し、そこに名前を表示させるHTMLを生成しているプログラムです。

この流れでログインしたユーザー名の表示が出来るようになりました！

全コード[GitHub](https://github.com/toshiyukiyosi/testvideo)に上げています。

今後の課題

* 対応ブラウザを増やす（現在はGoogle Chromeのみ）
* FullScreenにした時にもユーザー名を表示させる、全画面時の画面編集機能を追加する

などです。
まだまだ、稚拙なコードの書き方なので精進したいと思います。

間違い、改善などがありましたら、よろしくお願いします。

読んでくださりありがとうございました。
以上です