WebSocketの挙動を確かめる

WebSocketに関する説明とWebSocketを利用した簡単なサンプルを作成してみました。

まずは、WebSocketについて説明します。

<h3>WebSocketとは</h3>
WebSocketとはブラウザとサーバとの間で双方向通信を行うための通信企画です。

使用例としてはWeb会議やチャットなどがあります。

<h3>WebSocket API</h3>
<a href="https://developer.mozilla.org/ja/docs/Web/API/WebSocket">WebSocket</a>にドキュメントがあります。

重要な概念としては以下があります。
<ul>
<li>コンストラクタ</li>
<li>インスタンスプロパティ</li>
<li>インスタンスメソッド</li>
<li>イベント</li>
</ul>

コンストラクタで接続先のURLを設定します。
イベントでWebSocketが接続に成功した時やエラーが発生した時やWebSocketの接続が終わった場合の管理ができます。

<h3>WebSocket利用したサンプル</h3>
WebSocketはクライアント（ブラウザ）側とサーバ側の実装が必要です。

<b>サーバ側の実装</b>から始めていきます。

まずはterminalを開いてフォルダを作成できるPATHに移動してください。

```terminal
# WebSocketのサンプルアプリケーションを作成するフォルダを作成します。
mkdir websocket_sample
cd websocket_sample

# プロジェクト用のpackage.jsonファイルが作成します。
npm init -y
```
package.jsonに"type": "module"を追加します。
package.jsonが以下のようになっていればOKです。

```json
{
  "name": "websocket_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module"
}
```

```
# wsはWebSocketのクライアントとサーバの機能を持つライブラリです。
# wsをインストールします。
npm install ws

# index.jsを作成します。
touch index.js
```

index.jsにコードを記述します。
```JavaScript
import { WebSocketServer } from 'ws';
var wss = new WebSocketServer({ port: 8080 });

wss.on('listening',function(){
  console.log('server listening');
});

wss.on('connection', function(websocket) {
  websocket.on('message', function(message) {
    console.log("Received: " + message);

    wss.clients.forEach(function(client){
      client.send('Received: ' + message+' : '+new Date());
    });
  });

  websocket.on('close', function(){
    console.log('I lost a client');
  });
});
```

先ほど作成したプログラムを実行します。
```terminal
node index.js
```

<b>クライアント側の実装</b>を行います。
先ほどのフォルダとは別にindex.htmlを作成します。
```terminal
touch index.html
```
index.htmlには以下のコードを書きます。

```html
<!DOCTYPE html>
<html lang='ja'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='ie=edge'>
    <title>Document</title>
</head>
<body>
  <input type='button' id='button' value='送信'>
  <script>
    // WebSocketプロトコルの場合はws, wssを指定する
    var webSocket = new WebSocket('ws://127.0.0.1:8080');
    // Socket 接続が完了した時の処理
    webSocket.addEventListener('open', (event) => {
      console.log('Socket 接続成功');
    });
    // サーバーからデータを受け取る処理
    webSocket.addEventListener('message', (event) => {
      console.log(event.data);
    });
    // Socket 接続が終了した時の処理
    webSocket.addEventListener('close', (event) => {
      console.log('Socket 接続終了');
    });
    // Socket 接続でエラーが発生した時の処理
    webSocket.addEventListener('error', (event) => {
      console.log('Socket 接続でエラーが発生しました');
    });
    document.addEventListener('DOMContentLoaded', (event) => {
      // サーバーにデータを送る
      document.getElementById('button').addEventListener('click', function(event){
        webSocket.send('hello');
      });
    });
  </script>
</body>
</html>

```

コードが完成したのでindex.htmlファイルをブラウザで開いてみましょう。
![socket接続.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135402/cb5c0593-55e4-1010-dd3e-dac508c3ef03.png)

このように<b>送信ボタン</b>が表示されていればOKです。
開発者ツールを開いて(cmd + opt + i)接続を確認しましょう。

送信ボタンを押すとサーバにリクエストが送信され、サーバからも値が返ってくることがわかります。

![socket通信中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135402/eab4b332-3edf-f0e4-bee8-e1eb60ac393a.png)

<a href="https://github.com/websockets/ws">wi</a>には他のAPIやイベントも記載されています。

<h3>参考資料</h3>
<a href="https://qiita.com/okumurakengo/items/a8ccea065f5659d1a1de">5分で動かせるwebsocketのサンプル3つ</a>

<a href="https://www.youtube.com/watch?v=X7j6raOVXuU&list=PLYxzS__5yYQnRizvwNYWwzFjd9J4ni_Ga">WebSocket Tutorial</a>