Webrtc-text-demo

提供:Dev Guides
移動先:案内検索

WebRTC-テキストデモ

この章では、別々のデバイス上の2人のユーザーがWebRTCを使用して互いにメッセージを送信できるようにするクライアントアプリケーションを構築します。 アプリケーションには2つのページがあります。 1つはログイン用で、もう1つは別のユーザーにメッセージを送信するためのものです。

ログインしてメッセージページを送信

2つのページは_div_タグになります。 ほとんどの入力は、単純なイベントハンドラーを介して行われます。

シグナリングサーバー

WebRTC接続を作成するには、クライアントはWebRTCピア接続を使用せずにメッセージを転送できる必要があります。 ここで、HTML5 WebSockets-2つのエンドポイント間の双方向ソケット接続-WebサーバーとWebブラウザーを使用します。 それでは、WebSocketライブラリの使用を始めましょう。 _server.js_ファイルを作成し、次のコードを挿入します-

//require our websocket library
var WebSocketServer = require('ws').Server;

//creating a websocket server at port 9090
var wss = new WebSocketServer({port: 9090});

//when a user connects to our sever
wss.on('connection', function(connection) {
   console.log("user connected");

  //when server gets a message from a connected user
   connection.on('message', function(message) {
      console.log("Got message from a user:", message);
   });

   connection.send("Hello from server");
});

最初の行には、すでにインストールされているWebSocketライブラリが必要です。 次に、ポート9090にソケットサーバーを作成します。 次に、_connection_イベントをリッスンします。 このコードは、ユーザーがサーバーにWebSocket接続するときに実行されます。 次に、ユーザーから送信されたメッセージを聞きます。 最後に、接続したユーザーに「サーバーからこんにちは」という応答を送信します。

シグナリングサーバーでは、接続ごとに文字列ベースのユーザー名を使用するため、メッセージの送信先がわかります。 _connection_ハンドラーを少し変更しましょう-

connection.on('message', function(message) {
   var data;

  //accepting only JSON messages
   try {
      data = JSON.parse(message);
   } catch (e) {
      console.log("Invalid JSON");
      data = {};
   }
});

この方法では、JSONメッセージのみを受け入れます。 次に、接続しているすべてのユーザーをどこかに保存する必要があります。 単純なJavascriptオブジェクトを使用します。 私たちのファイルの上部を変更します-

//require our websocket library
var WebSocketServer = require('ws').Server;

//creating a websocket server at port 9090
var wss = new WebSocketServer({port: 9090});

//all connected to the server users
var users = {};

クライアントからのメッセージごとに_type_フィールドを追加します。 たとえば、ユーザーがログインする場合は、_login_タイプのメッセージを送信します。 それを定義しましょう-

connection.on('message', function(message) {
   var data;

  //accepting only JSON messages
   try {
      data = JSON.parse(message);
   } catch (e) {
      console.log("Invalid JSON");
      data = {};
   }

  //switching type of the user message
   switch (data.type) {
     //when a user tries to login
      case "login":
         console.log("User logged:", data.name);

        //if anyone is logged in with this username then refuse
         if(users[data.name]) {
            sendTo(connection, {
               type: "login",
               success: false
            });
         } else {
           //save user connection on the server
            users[data.name] = connection;
            connection.name = data.name;

            sendTo(connection, {
               type: "login",
               success: true
            });
         }

         break;

      default:
         sendTo(connection, {
            type: "error",
            message: "Command no found: " + data.type
         });

         break;
   }
});

ユーザーが_login_タイプでメッセージを送信する場合、私たちは-

  • 誰かがこのユーザー名で既にログインしているかどうかを確認してください。
  • その場合は、ユーザーにログインに失敗したことを伝えます。
  • このユーザー名を使用しているユーザーがいない場合は、ユーザー名をキーとして接続オブジェクトに追加します。
  • コマンドが認識されない場合、エラーを送信します。

次のコードは、接続にメッセージを送信するためのヘルパー関数です。 _server.js_ファイルに追加します-

function sendTo(connection, message) {
   connection.send(JSON.stringify(message));
}

ユーザーが切断したら、その接続をクリーンアップする必要があります。 _close_イベントが発生したときにユーザーを削除できます。 _connection_ハンドラに次のコードを追加します-

connection.on("close", function() {
   if(connection.name) {
      delete users[connection.name];
   }
});

ログインに成功した後、ユーザーは別の電話をかけたいと考えています。 彼はそれを達成するために別のユーザーに_offer_する必要があります。 _offer_ハンドラを追加します-

case "offer":
  //for ex. UserA wants to call UserB
   console.log("Sending offer to: ", data.name);

  //if UserB exists then send him offer details
   var conn = users[data.name];

   if(conn != null){
  //setting that UserA connected with UserB
   connection.otherName = data.name;

      sendTo(conn, {
         type: "offer",
         offer: data.offer,
         name: connection.name
      });

   break;

まず、呼び出しようとしているユーザーの_connection_を取得します。 存在する場合は、_offer_詳細を送信します。 また、_otherName_を_connection_オブジェクトに追加します。 これは、後で簡単に見つけられるようにするためです。

応答への応答には、_offer_ハンドラーで使用したのと同様のパターンがあります。 サーバーは、すべてのメッセージを別のユーザーに_answer_として渡すだけです。 _offer_ハンドラの後に次のコードを追加します-

case "answer":
   console.log("Sending answer to: ", data.name);

  //for ex. UserB answers UserA
   var conn = users[data.name];

   if(conn != null) {
      connection.otherName = data.name;
      sendTo(conn, {
         type: "answer",
         answer: data.answer
      });
   }

   break;

最後の部分は、ユーザー間のICE候補の処理です。 ユーザー間でメッセージを渡すだけで同じ手法を使用します。 主な違いは、候補メッセージがユーザーごとに複数回発生する可能性があることです。 _candidate_ハンドラーを追加します-

case "candidate":
   console.log("Sending candidate to:",data.name);
   var conn = users[data.name];

   if(conn != null) {
      sendTo(conn, {
         type: "candidate",
         candidate: data.candidate
      });
   }

   break;

ユーザーが別のユーザーから切断できるようにするには、ハングアップ機能を実装する必要があります。 また、サーバーにすべてのユーザー参照を削除するように指示します。 _leave_ハンドラを追加します-

case "leave":
   console.log("Disconnecting from", data.name);
   var conn = users[data.name];
   conn.otherName = null;

  //notify the other user so he can disconnect his peer connection
   if(conn != null) {
      sendTo(conn, {
         type: "leave"
      });
   }

   break;

これにより、他のユーザーに_leave_イベントも送信されるため、ピア接続を適宜切断できます。 また、ユーザーが信号サーバーから接続をドロップした場合も処理する必要があります。 _close_ハンドラを変更しましょう-

connection.on("close", function() {

   if(connection.name) {
      delete users[connection.name];

      if(connection.otherName) {
         console.log("Disconnecting from ", connection.otherName);
         var conn = users[connection.otherName];
         conn.otherName = null;

         if(conn != null) {
            sendTo(conn, {
               type: "leave"
            });
         }
      }
   }
});

以下は、私たちのシグナルサーバーのコード全体です-

//require our websocket library
var WebSocketServer = require('ws').Server;

//creating a websocket server at port 9090
var wss = new WebSocketServer({port: 9090});

//all connected to the server users
var users = {};

//when a user connects to our sever
wss.on('connection', function(connection) {

   console.log("User connected");

  //when server gets a message from a connected user
   connection.on('message', function(message) {

      var data;
     //accepting only JSON messages
      try {
         data = JSON.parse(message);
      } catch (e) {
         console.log("Invalid JSON");
         data = {};
      }

     //switching type of the user message
      switch (data.type) {
        //when a user tries to login
         case "login":
            console.log("User logged", data.name);
           //if anyone is logged in with this username then refuse
            if(users[data.name]) {
               sendTo(connection, {
                  type: "login",
                  success: false
               });
            } else {
              //save user connection on the server
               users[data.name] = connection;
               connection.name = data.name;

               sendTo(connection, {
                  type: "login",
                  success: true
               });
            }

            break;

         case "offer":
           //for ex. UserA wants to call UserB
            console.log("Sending offer to: ", data.name);

           //if UserB exists then send him offer details
            var conn = users[data.name];

            if(conn != null) {
              //setting that UserA connected with UserB
               connection.otherName = data.name;

               sendTo(conn, {
                  type: "offer",
                  offer: data.offer,
                  name: connection.name
               });
            }

            break;

         case "answer":
            console.log("Sending answer to: ", data.name);
           //for ex. UserB answers UserA
            var conn = users[data.name];

            if(conn != null) {
               connection.otherName = data.name;
               sendTo(conn, {
                  type: "answer",
                  answer: data.answer
               });
            }

            break;

         case "candidate":
            console.log("Sending candidate to:",data.name);
            var conn = users[data.name];

            if(conn != null) {
               sendTo(conn, {
                  type: "candidate",
                  candidate: data.candidate
               });
            }

            break;

         case "leave":
            console.log("Disconnecting from", data.name);
            var conn = users[data.name];
            conn.otherName = null;

           //notify the other user so he can disconnect his peer connection
            if(conn != null) {
               sendTo(conn, {
                  type: "leave"
               });
            }

            break;

         default:
            sendTo(connection, {
               type: "error",
               message: "Command not found: " + data.type
            });

            break;

      }
   });

  //when user exits, for example closes a browser window
  //this may help if we are still in "offer","answer" or "candidate" state
   connection.on("close", function() {

      if(connection.name) {
         delete users[connection.name];

         if(connection.otherName) {
            console.log("Disconnecting from ", connection.otherName);
            var conn = users[connection.otherName];
            conn.otherName = null;

            if(conn != null) {
               sendTo(conn, {
                  type: "leave"
               });
            }
         }
      }
   });

   connection.send("Hello world");

});

function sendTo(connection, message) {
   connection.send(JSON.stringify(message));
}

クライアントアプリケーション

このアプリケーションをテストする1つの方法は、2つのブラウザータブを開き、互いにメッセージを送信しようとすることです。

まず、_bootstrap_ライブラリをインストールする必要があります。 ブートストラップは、Webアプリケーションを開発するためのフロントエンドフレームワークです。 詳細については、http://getbootstrap.com/[[[1]]]をご覧ください。たとえば、「textchat」という名前のフォルダーを作成します。 これがルートアプリケーションフォルダになります。 このフォルダ内にファイル_package.json_を作成し(npmの依存関係を管理するために必要です)、次を追加します-

{
   "name": "webrtc-textochat",
   "version": "0.1.0",
   "description": "webrtc-textchat",
   "author": "Author",
   "license": "BSD-2-Clause"
}

次に、_npm install bootstrap_を実行します。 これにより、ブートストラップライブラリが_textchat/node_modules_フォルダーにインストールされます。

次に、基本的なHTMLページを作成する必要があります。 次のコードでルートフォルダに_indexl_ファイルを作成します-

<html>

   <head>
      <title>WebRTC Text Demo</title>
      <link rel = "stylesheet" href = "node_modules/bootstrap/dist/css/bootstrap.min.css"/>
   </head>

   <style>
      body {
         background: #eee;
         padding: 5% 0;
      }
   </style>

   <body>
      <div id = "loginPage" class = "container text-center">

         <div class = "row">
            <div class = "col-md-4 col-md-offset-4">
               <h2>WebRTC Text Demo. Please sign in</h2>
               <label for = "usernameInput" class = "sr-only">Login</label>
               <input type = "email" id = "usernameInput"
                  class = "form-control formgroup" placeholder = "Login"
                  required = "" autofocus = "">
               <button id = "loginBtn" class = "btn btn-lg btn-primary btnblock">
                  Sign in</button>
            </div>
         </div>

      </div>

      <div id = "callPage" class = "call-page container">

         <div class = "row">
            <div class = "col-md-4 col-md-offset-4 text-center">
               <div class = "panel panel-primary">
                  <div class = "panel-heading">Text chat</div>
                  <div id = "chatarea" class = "panel-body text-left"></div>
               </div>
            </div>
         </div>

         <div class = "row text-center form-group">
            <div class = "col-md-12">
               <input id = "callToUsernameInput" type = "text"
                  placeholder = "username to call"/>
               <button id = "callBtn" class = "btn-success btn">Call</button>
               <button id = "hangUpBtn" class = "btn-danger btn">Hang Up</button>
            </div>
         </div>

         <div class = "row text-center">
            <div class = "col-md-12">
               <input id = "msgInput" type = "text" placeholder = "message"/>
               <button id = "sendMsgBtn" class = "btn-success btn">Send</button>
            </div>
         </div>

      </div>

      <script src = "client.js"></script>

   </body>

</html>

このページはおなじみのはずです。 bootstrap cssファイルを追加しました。 また、2つのページを定義しました。 最後に、ユーザーから情報を取得するためのテキストフィールドとボタンをいくつか作成しました。 「チャット」ページには、すべてのメッセージが表示される「chatarea」IDを持つdivタグが表示されます。 _client.js_ファイルへのリンクが追加されていることに注意してください。

次に、シグナリングサーバーとの接続を確立する必要があります。 次のコードでルートフォルダに_client.js_ファイルを作成します-

//our username
var name;
var connectedUser;

//connecting to our signaling server
var conn = new WebSocket('ws://localhost:9090');

conn.onopen = function () {
   console.log("Connected to the signaling server");
};

//when we got a message from a signaling server
conn.onmessage = function (msg) {
   console.log("Got message", msg.data);

   var data = JSON.parse(msg.data);

   switch(data.type) {
      case "login":
         handleLogin(data.success);
         break;
     //when somebody wants to call us
      case "offer":
         handleOffer(data.offer, data.name);
         break;
      case "answer":
         handleAnswer(data.answer);
         break;
     //when a remote peer sends an ice candidate to us
      case "candidate":
         handleCandidate(data.candidate);
         break;
      case "leave":
         handleLeave();
         break;
      default:
         break;
   }
};

conn.onerror = function (err) {
   console.log("Got error", err);
};

//alias for sending JSON encoded messages
function send(message) {
  //attach the other peer username to our messages
   if (connectedUser) {
      message.name = connectedUser;
   }

   conn.send(JSON.stringify(message));
};

ここで、_node server_を介してシグナルサーバーを実行します。 次に、ルートフォルダー内で_static_コマンドを実行し、ブラウザー内でページを開きます。 次のコンソール出力が表示されるはずです-

コンソール出力

次の手順では、一意のユーザー名でユーザーログインを実装します。 ユーザー名をサーバーに送信するだけで、ユーザー名が取得されたかどうかがわかります。 _client.js_ファイルに次のコードを追加します-

//******
//UI selectors block
//******

var loginPage = document.querySelector('#loginPage');
var usernameInput = document.querySelector('#usernameInput');
var loginBtn = document.querySelector('#loginBtn');

var callPage = document.querySelector('#callPage');
var callToUsernameInput = document.querySelector('#callToUsernameInput');
var callBtn = document.querySelector('#callBtn');

var hangUpBtn = document.querySelector('#hangUpBtn');
callPage.style.display = "none";

//Login when the user clicks the button
loginBtn.addEventListener("click", function (event) {
   name = usernameInput.value;

   if (name.length > 0) {
      send({
         type: "login",
         name: name
      });
   }

});

function handleLogin(success) {

   if (success === false) {
      alert("Ooops...try a different username");
   } else {
      loginPage.style.display = "none";
      callPage.style.display = "block";

     //**********************
     //Starting a peer connection
     //**********************
   }

};

まず、ページ上の要素への参照を選択します。 呼び出しページを非表示にします。 次に、ログインボタンにイベントリスナーを追加します。 ユーザーがクリックすると、ユーザー名をサーバーに送信します。 最後に、handleLoginコールバックを実装します。 ログインが成功した場合、呼び出しページを表示し、ピア接続を設定し、データチャネルを作成します。

データチャネルとのピア接続を開始するには、以下が必要です-

  • RTCPeerConnectionオブジェクトを作成します
  • RTCPeerConnectionオブジェクト内にデータチャネルを作成します

「UIセレクターブロック」に次のコードを追加します-

var msgInput = document.querySelector('#msgInput');
var sendMsgBtn = document.querySelector('#sendMsgBtn');
var chatArea = document.querySelector('#chatarea');

var yourConn;
var dataChannel;

_handleLogin_関数を変更します-

function handleLogin(success) {
   if (success === false) {
      alert("Ooops...try a different username");
   } else {
      loginPage.style.display = "none";
      callPage.style.display = "block";

     //**********************
     //Starting a peer connection
     //**********************

     //using Google public stun server
      var configuration = {
         "iceServers": [{ "url": "stun:stun2.1.google.com:19302" }]
      };

      yourConn = new webkitRTCPeerConnection(configuration, {optional: [{RtpDataChannels: true}]});

     //Setup ice handling
      yourConn.onicecandidate = function (event) {
         if (event.candidate) {
            send({
               type: "candidate",
               candidate: event.candidate
            });
         }
      };

     //creating data channel
      dataChannel = yourConn.createDataChannel("channel1", {reliable:true});

      dataChannel.onerror = function (error) {
         console.log("Ooops...error:", error);
      };

     //when we receive a message from the other peer, display it on the screen
      dataChannel.onmessage = function (event) {
         chatArea.innerHTML += connectedUser + ": " + event.data + "<br/>";
      };

      dataChannel.onclose = function () {
         console.log("data channel is closed");
      };
   }
};

ログインが成功した場合、アプリケーションは_RTCPeerConnection_オブジェクトを作成し、見つかったすべてのicecandidatesを他のピアに送信する_onicecandidate_ハンドラーをセットアップします。 また、dataChannelも作成します。 RTCPeerConnectionオブジェクトを作成する場合、ChromeまたはOperaを使用している場合、コンストラクターの2番目の引数はオプションです:[\ {RtpDataChannels:true}]は必須です。 次のステップは、他のピアへのオファーを作成することです。 ユーザーがオファーを取得すると、_answer_を作成し、ICE候補の取引を開始します。 _client.js_ファイルに次のコードを追加します-

//initiating a call
callBtn.addEventListener("click", function () {
   var callToUsername = callToUsernameInput.value;

   if (callToUsername.length > 0) {

      connectedUser = callToUsername;

     //create an offer
      yourConn.createOffer(function (offer) {

         send({
            type: "offer",
            offer: offer
         });

         yourConn.setLocalDescription(offer);

      }, function (error) {
         alert("Error when creating an offer");
      });
   }
});

//when somebody sends us an offer
function handleOffer(offer, name) {
   connectedUser = name;
   yourConn.setRemoteDescription(new RTCSessionDescription(offer));

  //create an answer to an offer
   yourConn.createAnswer(function (answer) {
      yourConn.setLocalDescription(answer);

      send({
         type: "answer",
         answer: answer
      });

   }, function (error) {
      alert("Error when creating an answer");
   });
};

//when we got an answer from a remote user
function handleAnswer(answer) {
   yourConn.setRemoteDescription(new RTCSessionDescription(answer));
};

//when we got an ice candidate from a remote user
function handleCandidate(candidate) {
   yourConn.addIceCandidate(new RTCIceCandidate(candidate));
};

Callボタンに_click_ハンドラーを追加して、オファーを開始します。 次に、_onmessage_ハンドラーが期待するいくつかのハンドラーを実装します。 両方のユーザーが接続するまで、非同期で処理されます。

次のステップは、ハングアップ機能の実装です。 これにより、データの送信が停止され、他のユーザーにデータチャネルを閉じるように指示されます。 次のコードを追加します-

//hang up
hangUpBtn.addEventListener("click", function () {
   send({
      type: "leave"
   });

   handleLeave();
});

function handleLeave() {
   connectedUser = null;
   yourConn.close();
   yourConn.onicecandidate = null;
};

ユーザーがハングアップボタンをクリックすると-

  • 他のユーザーに「leave」メッセージを送信します。
  • RTCPeerConnectionとデータチャネルを閉じます。

最後のステップは、別のピアにメッセージを送信することです。 「メッセージ」ボタンに「クリック」ハンドラーを追加します-

//when user clicks the "send message" button
sendMsgBtn.addEventListener("click", function (event) {
   var val = msgInput.value;
   chatArea.innerHTML += name + ": " + val + "<br/>";

  //sending a message to a connected peer
   dataChannel.send(val);
   msgInput.value = "";
});

次に、コードを実行します。 2つのブラウザータブを使用してサーバーにログインできるはずです。 次に、他のユーザーへのピア接続を設定して、メッセージを送信し、「ハングアップ」ボタンをクリックしてデータチャネルを閉じます。

コードの出力

以下は_client.js_ファイル全体です-

//our username
var name;
var connectedUser;

//connecting to our signaling server
var conn = new WebSocket('ws://localhost:9090');

conn.onopen = function () {
   console.log("Connected to the signaling server");
};

//when we got a message from a signaling server
conn.onmessage = function (msg) {
   console.log("Got message", msg.data);
   var data = JSON.parse(msg.data);

   switch(data.type) {
      case "login":
         handleLogin(data.success);
         break;
     //when somebody wants to call us
      case "offer":
         handleOffer(data.offer, data.name);
         break;
      case "answer":
         handleAnswer(data.answer);
         break;
     //when a remote peer sends an ice candidate to us
      case "candidate":
         handleCandidate(data.candidate);
         break;
      case "leave":
         handleLeave();
         break;
      default:
         break;
   }
};

conn.onerror = function (err) {
   console.log("Got error", err);
};

//alias for sending JSON encoded messages
function send(message) {

  //attach the other peer username to our messages
   if (connectedUser) {
      message.name = connectedUser;
   }

   conn.send(JSON.stringify(message));
};

//******
//UI selectors block
//******

var loginPage = document.querySelector('#loginPage');
var usernameInput = document.querySelector('#usernameInput');
var loginBtn = document.querySelector('#loginBtn');

var callPage = document.querySelector('#callPage');
var callToUsernameInput = document.querySelector('#callToUsernameInput');
var callBtn = document.querySelector('#callBtn');

var hangUpBtn = document.querySelector('#hangUpBtn');
var msgInput = document.querySelector('#msgInput');
var sendMsgBtn = document.querySelector('#sendMsgBtn');

var chatArea = document.querySelector('#chatarea');
var yourConn;
var dataChannel;
callPage.style.display = "none";

//Login when the user clicks the button
loginBtn.addEventListener("click", function (event) {
   name = usernameInput.value;

   if (name.length > 0) {
      send({
         type: "login",
         name: name
      });
   }

});

function handleLogin(success) {

   if (success === false) {
      alert("Ooops...try a different username");
   } else {
      loginPage.style.display = "none";
      callPage.style.display = "block";

     //**********************
     //Starting a peer connection
     //**********************

     //using Google public stun server
      var configuration = {
         "iceServers": [{ "url": "stun:stun2.1.google.com:19302" }]
      };

      yourConn = new webkitRTCPeerConnection(configuration, {optional: [{RtpDataChannels: true}]});

     //Setup ice handling
      yourConn.onicecandidate = function (event) {
         if (event.candidate) {
            send({
               type: "candidate",
               candidate: event.candidate
            });
         }
      };

     //creating data channel
      dataChannel = yourConn.createDataChannel("channel1", {reliable:true});

      dataChannel.onerror = function (error) {
         console.log("Ooops...error:", error);
      };

     //when we receive a message from the other peer, display it on the screen
      dataChannel.onmessage = function (event) {
         chatArea.innerHTML += connectedUser + ": " + event.data + "<br/>";
      };

      dataChannel.onclose = function () {
         console.log("data channel is closed");
      };

   }
};

//initiating a call
callBtn.addEventListener("click", function () {
   var callToUsername = callToUsernameInput.value;

   if (callToUsername.length > 0) {
      connectedUser = callToUsername;
     //create an offer
      yourConn.createOffer(function (offer) {
         send({
            type: "offer",
            offer: offer
         });
         yourConn.setLocalDescription(offer);
      }, function (error) {
         alert("Error when creating an offer");
      });
   }

});

//when somebody sends us an offer
function handleOffer(offer, name) {
   connectedUser = name;
   yourConn.setRemoteDescription(new RTCSessionDescription(offer));

  //create an answer to an offer
   yourConn.createAnswer(function (answer) {
      yourConn.setLocalDescription(answer);
      send({
         type: "answer",
         answer: answer
      });
   }, function (error) {
      alert("Error when creating an answer");
   });

};

//when we got an answer from a remote user
function handleAnswer(answer) {
   yourConn.setRemoteDescription(new RTCSessionDescription(answer));
};

//when we got an ice candidate from a remote user
function handleCandidate(candidate) {
   yourConn.addIceCandidate(new RTCIceCandidate(candidate));
};

//hang up
hangUpBtn.addEventListener("click", function () {
   send({
      type: "leave"
   });

   handleLeave();
});

function handleLeave() {
   connectedUser = null;
   yourConn.close();
   yourConn.onicecandidate = null;
};

//when user clicks the "send message" button
sendMsgBtn.addEventListener("click", function (event) {
   var val = msgInput.value;
   chatArea.innerHTML += name + ": " + val + "<br/>";

  //sending a message to a connected peer
   dataChannel.send(val);
   msgInput.value = "";
});