uWebSockets.js を使った Webサーバー・WebSocketサーバーのお試し【Node.js】


以下の記事を書いた時に見かけた「uWebSockets」が気になって、情報を少し見てみたり、試してみたというものです。

●Socket.IO の最新版 4.x の情報を見てみる（2022年3月） - Qiita
　https://qiita.com/youtoy/items/c57158f4a08e478dff57

### Socket.IO のドキュメント内での記載
Socket.IO のドキュメント内だと、具体的に以下の部分などで登場しています。

![発見した元1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3b615ebd-8a58-b119-4fa1-7748541ac6a4.jpeg)
![発見した元2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4fa54555-b0c5-76df-5bab-565a9e4a9000.png)

## uWebSockets.js を試す
まず、uWebSockets.js の GitHubリポジトリを見てみます。

●uNetworking/uWebSockets.js: μWebSockets for Node.js back-ends
　https://github.com/uNetworking/uWebSockets.js
![uWebSockets.js](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/92461fd3-adcc-6eef-c81a-b3af1d4f24fd.png)

以下が記事執筆時点での、公式ドキュメントの最新版のようです。
●uWebSockets.js v20.4.0 documentation
　https://unetworking.github.io/uWebSockets.js/generated/

### 利用するための準備
利用するためには、以下の yarnコマンドを使った準備が必要になるようです。
![利用するための準備](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3ae40dc0-9c96-0392-06fb-0b15fc5d9289.png)

具体的には、以下となります。

```bash
$ yarn add uWebSockets.js@uNetworking/uWebSockets.js#v20.3.0
```

### お試しする時の参照先
実際に uWebSockets.js を試していく際に、参照元の情報として「[examples](https://github.com/uNetworking/uWebSockets.js/tree/master/examples)」の中のいくつかの内容を見てみます。

- HelloWorld.js
   - https://github.com/uNetworking/uWebSockets.js/blob/master/examples/HelloWorld.js
- WebSockets.js
   - https://github.com/uNetworking/uWebSockets.js/blob/master/examples/WebSockets.js

この HelloWorld.js と WebSockets.js を試してみることにします。

#### HelloWorld.js を元にしたお試し
HelloWorld.js を元にしたお試しをやっていきます。
`require` の部分や `uWS.App` の部分などを少し変更して、以下の内容にしました。

```javascript
const uWS = require('uWebSockets.js');
const port = 9001;

const app = uWS.App().get('/*', (res, req) => {
  res.end('Hello World!');
}).listen(port, (token) => {
  if (token) {
    console.log('Listening to port ' + port);
  } else {
    console.log('Failed to listen to port ' + port);
  }
});
```

上記のプログラムを nodeコマンドで実行してサーバーを立ち上げ、その後に、ブラウザで `http://127.0.0.1:9001/` にアクセスしてみます。
無事に、サーバーからのレスポンスが返ってきているのが確認できました。
![HelloWorld.jsを試した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c029659d-ebc0-1851-9567-1233184f165a.png)

#### WebSockets.js を元にしたお試し
次に WebSockets.js を元にしたお試しをやっていきます。
先ほどと同様に、これも少し書きかえをして使ってみます。

```javascript
const uWS = require('uWebSockets.js');
const port = 9001;

const app = uWS.App().get('/*', (res, req) => {
  res.end('Hello World!');
}).ws('/*', {
  compression: uWS.SHARED_COMPRESSOR,
  maxPayloadLength: 16 * 1024 * 1024,
  idleTimeout: 12,
  open: (ws) => {
    console.log('A WebSocket connected!');
  },
  message: (ws, message, isBinary) => {
    let ok = ws.send(message, isBinary);
  },
  drain: (ws) => {
    console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
  },
  close: (ws, code, message) => {
    console.log('WebSocket closed');
  }
}).any('/*', (res, req) => {
  res.end('Nothing to see here!');
}).listen(port, (token) => {
  if (token) {
    console.log('Listening to port ' + port);
  } else {
    console.log('Failed to listen to port ' + port);
  }
});
```

また今後も上記のプログラムを nodeコマンドで実行してサーバーを立ち上げ、その後に、ブラウザで `http://127.0.0.1:9001/` にアクセスしてみます。
今度も無事に、サーバーからのレスポンスが返ってきているのが確認できました。
![HelloWorld.jsを試した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c029659d-ebc0-1851-9567-1233184f165a.png)

そして、今回は WebSocketサーバーも立ち上がっているので、以下の記事を書いた時と同じ方法で WebSocketクライアントを作成し、WebSocketによる通信を試します。

●Node.js のフレームワークの Fastify と WebSocket を利用可能にする fastify-websocket を軽く触ってみる - Qiita
　https://qiita.com/youtoy/items/7c5a318278e397602b76

上記の記事では HTMLファイルで WebSocketクライアントを用意していました。
そのポート番号の部分を今回のサーバーに合うように少し書きかえて、以下のファイルを用意しました。

```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocketクライアント</title>
</head>

<body>
  <input type="button" id="button" value="データの送信">

  <script>
    const socket = new WebSocket('ws://127.0.0.1:9001');

    socket.addEventListener('open', function (event) {
      console.log('サーバーへの接続成功');
    });

    socket.addEventListener('message', function (event) {
      console.log('Message from server ', event.data);
    });

    const button = document.getElementById('button');
    button.addEventListener('click', function () {
      socket.send('hello from client');
    });
  </script>
</body>

</html>
```

上記の HTMLファイルをブラウザで開き、開発者ツールのコンソールを開いた状態で、ブラウザ上に表示されたボタンを押してみます。
その結果、以下のようにコンソールにサーバーから受信したデータ（クライアントから送ったデータがオウム返しされたもの）を表示することができました。
![WebSocketサーバーを試した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d3e7f1e6-32ee-32d9-f4de-abfd00b34daf.png)

## おわりに
今回、uWebSockets.js を使った Webサーバー・WebSocketサーバーを試してみて、意図通りに動作させることができました。

今回は、とりあえず動作させてみるところまでやってみましたが、Node.js用の Webアプリ用フレームワークや、WebSocketサーバーを構築する仕組みは他にもあるため、それらとの違いを確認してみたいところです。