Node JS WebSocketプログラミング例
Published: 2023-11-28 14:16:37

これを読んでいるということは、おそらくどちらか一方が開始できる双方向通信を必要とするアプリケーションやサービスの作成に興味があるのでしょう。Node JavaScript（Node.js）は、このようなユースケースを念頭に設計されたWebSocketを使用して、このアプリケーションを迅速に開発し、デプロイするために使用することができます。

WebSocketとは何ですか？
----------------

A [ウェブソケット](https://www.pubnub.com/guides/what-are-websockets-and-when-should-you-use-them/)はコンピュータ通信プロトコルで [二重](https://en.wikipedia.org/wiki/Duplex_(telecommunications))通信チャネルを提供するコンピュータ通信プロトコルです。つまり、インターネットに接続可能なデバイス同士が通信を行うことができ、一方がクライアント、もう一方がサーバーとして機能し、どちらも通信を開始することができます。

### どのようなアプリケーションがWebSocketを使用しますか？

WebSocketプロトコルは、リアルタイム通信を必要とするソリューションで使用されます：

-   [チャットアプリ](https://www.pubnub.com/solutions/chat/)
    
-   [株価の更新](https://www.pubnub.com/solutions/data-streaming/)
    
-   [地図上のライブ位置追跡](https://www.pubnub.com/solutions/geolocation/)
    
-   [観客とのライブ・インタラクション](https://www.pubnub.com/solutions/live-audience-engagement/)
    
-   [オンライン・オークション](https://www.pubnub.com/solutions/marketplaces/)
    
-   [IoTデバイスの更新](https://www.pubnub.com/solutions/iot-device-control/)
    

WebSocketは、複数のデバイスまたはプロセス間でTCPソケット接続を作成します。後述するように、同様の機能は以下を使用して実装することができる。 [HTTPロングポーリング](https://www.pubnub.com/learn/glossary/http-long-polling/)やホストされたpub/subサービスを使用して実装することもできますが、まずはWebSocketとNode.jsを使用して簡単な例を構築してみましょう。

Node.jsはWebSocketに向いていますか？
--------------------------

はい、Node.jsは高速でスケーラブルなサーバーサイド環境を提供し、人気のある [wsライブラリ](https://www.npmjs.com/package/ws).

### なぜWebSocketにNode.jsを使うのですか？

Node.jsは、[イベント駆動型](https://www.pubnub.com/guides/event-driven-architecture/)、ノンブロッキングI/Oモデルを使用しており、WebSocketベースのアプリケーションのリソース要件を処理するのに適しています。

### Node.jsでWebSocketを実装する方法

以下のガイドでは、Node.js で WebSocket サーバーを作成し、ブラウザで実行されている WebSocket クライアントを使用してそのサーバーに接続する方法を説明します。

### Node.jsサーバは何個のWebSocket接続を処理できますか？

本番アプリケーションでは、同時に何万もの WebSocket 接続を処理できるかもしれませんが、正確な数は、サーバーのハードウェアリソース、ネットワーク帯域幅、アプリケーションロジックの複雑さなど、いくつかの要因に依存します。

Node.js WebSocket API の例 - 基本的なチャット・アプリケーション
--------------------------------------------

このブログに関連するすべてのソースコードは [GitHub](https://github.com/PubNubDevelopers/nodejs-websocket-examples)

WebSocket を使った基本的なチャット・アプリケーションを構築するには、クライアントとサーバー・コンポーネントの両方が必要です。

サーバには Node.js を使用し、クライアント側のコードは Chrome などのウェブブラウザで実行します。

### Node.js WebSocketsコード（サーバー）

このアプリケーションには、ウェブサーバー[（HTTPサーバー](https://www.pubnub.com/guides/http/)）とウェブソケットサーバー（wss）の両方が必要です。 ウェブサーバーはクライアント（ブラウザーで動作）を読み込むことを可能にし、ウェブソケットサーバーは双方向のチャットメッセージを処理します。

### NodeJSでWebSocketサーバーを作成するには？

Node.jsアプリを作成して [Express.js](https://expressjs.com/)と[ws](https://www.npmjs.com/package/ws)パッケージの両方をインストールする。

```js
npm init [プロンプトに従い、デフォルトを受け入れる] npm install --save express npm install --save ws
```

ウェブサーバー部分は、ポート3000でクライアントに1つのウェブページ、websocket-client.htmlを提供します：

```js
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`Listening on ${3000}`))
```

WebSocket サーバーは、Node.js の WebSocket ライブラリ (ws) パッケージを使用すれば数行で作成できます：

```js
const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 })
```

### NodeJS の例で WebSocket イベントを書く

WebSocket サーバーのインスタンスを作成し、実行するポートを指定した後、WebSocket 接続が確立された後に発生するアクションを定義できます。 この例では、接続イベントをコンソールに書き込み、以前に接続したクライアントに受信したメッセージを転送します。WebSocketはHTTP/HTTPSと同じポート（つまり80と443）で動作するように設計されています。

```js
sockserver.on('connection', ws => { console.log('新しいクライアントが接続されました！') ws.send('接続が確立されました') ws.on('close', () => console.log('クライアントが切断されました！')) ws.on('message', data => { sockserver.clients.forEach(client => { console.log(`メッセージの配信: ${data}`) client.send(`${data}`) }) ws.onerror = function () { console.log('ウェブソケットエラー') } })
```

これでサーバー部分は完了です。ソケットでメッセージを受信するたびに、接続されているすべてのクライアントにメッセージをプロキシします。

index.jsのコードは次のようになる：

```js
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`Listening on ${3000}`)) const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 }) sockserver.on('connection', ws => { console.log('New client connected!') ws.send('connection established') ws.on('close', () => console.log('クライアントが切断されました！')) ws.on('message', data => { sockserver.clients.forEach(client => { console.log(`distributing message: ${data}`) client.send(`${data}`) }) ws.onerror = function () { console.log('ウェブソケットエラー') } })
```

そして、以下のようにコマンドラインから実行できる：

```js
node index.js
```

メッセージは、テキストまたはJSONエンコード（JSON.stringify）のいずれかにすることができます。このコードでは、デフォルトで utf-8 charset を使用しています。

### WebSocketsのコード例（クライアント/ブラウザ）

最新のウェブブラウザでウェブソケットを使用するために、追加のソフトウェアやパッケージをインストールする必要はありません。正しくフォーマットされた URI を提供することで、リスニング中の WebSocket を作成します：

```js
const webSocket = new WebSocket('ws://localhost:443/')；
```

そして、サーバーからメッセージを受信したときのイベントハンドラを定義します：

```js
webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += 'Message from server：' + event.data + "<br>"; }；
```

これで、WebSocketサーバーからデータを受信できるようになりました。

クライアントからメッセージ・イベントを送信するには、ソケット・オブジェクトに send() を実行します：

```js
webSocket.send('hello')
```

チャットアプリを機能させるには、入力フィールドと'メッセージの送信'ボタンを追加すればよいので、フロントエンドのHTMLコードは以下のようになります（簡潔にするためにスタイリングとCSSは省略されています）：

```js
<html> <head> </head> <body> <form id="input-form"> <label for="message">メッセージを入力してください：</label> <input type="text" id="message" name="message"><br><br> <input type="submit" value="Send"> </form> <div id="messages"></div> <script> const webSocket = new WebSocket('ws://localhost:443/'); webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += 'サーバーからのメッセージです：' + event.data + "<br>"; }; webSocket.addEventListener("open", () => { console.log("接続しました"); }); function sendMessage(event) { var inputMessage = document.getElementById('message') webSocket.send(inputMessage.value) inputMessage.value = "" event.preventDefault(); } document.getElementById('input-form').addEventListener('submit',sendMessage);</script> </body> </html>
```

HTMLページに "websocket-client.html "という名前を付け、ブラウザーのタブをいくつか立ち上げ、次の場所に移動する。 [http://localhost:3000](http://localhost:3000/)すべてのタブに受信したメッセージが表示されるはずです：

![](https://images.ctfassets.net/3prze68gbwl1/6fmgnp5AhVVAvBOt3jxdmQ/330a9faef0f816db63f34f6cf49ab0a6/node.js-websockets.png)

Node.jsサーバーなしで同じチャットアプリを作成する
----------------------------

サーバーを持っていない場合や、アプリケーションの将来の需要に対応するためにサーバー・インフラストラクチャを拡張することに懸念がある場合は、Socket.ioや [PubNub](https://www.pubnub.com/).

PubNubはグローバルに分散されたスケーラブルなクラウドプラットフォームであるため、バックエンドのサーバーのデプロイやメンテナンスを心配する必要はありません。 [PubNub SDK](https://www.pubnub.com/docs/sdks)はユーザーを識別し、特定のチャンネルにメッセージを送信することができ、購読しているユーザーだけがメッセージを受け取ることができます。

では、上で紹介したシンプルなチャットアプリはPubNubを使ってどのように書かれるのでしょうか？ PubNubの利点の1つは、以下の点です。 [プロトコルにとらわれない](https://support.pubnub.com/hc/en-us/articles/360051496552-Does-PubNub-use-WebSockets-or-some-other-protocol-)PubNubは'publish'と'subscribe'アーキテクチャ（pub/sub）を使って双方向のメッセージを送受信します。

### JavaScript SDKのコード例

まず、ヘッダーにPubNub JavaScript SDKをインクルードします：

```js
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script>.
```

受信メッセージを購読するには、PubNubインスタンスを作成し、チャネルを定義し、リスナーを追加します：

```js
var pubnub = new PubNub({ publishKey: 'demo', subscribeKey: 'demo', userId："" + Math.random() }) pubnub.subscribe({ channels: ['ws-channel'] }) pubnub.addListener({ message: payload => { console.log() document.getElementById('messages').innerHTML += 'クライアントからのメッセージ: ' + payload.message + "<br>"; })
```

このページは'ws-channel'でメッセージが受信されるたびに更新されます。 上記のコードでは'demo'キーを使用していますが、カスタムの [PubNubキー](https://admin.pubnub.com/#/register)を無料で入手できます。

PubNubでメッセージを送信するには、以前に購読したのと同じチャンネルで公開します：

```js
pubnub.publish({ channel: 'ws-channel', message: inputMessage.value })
```

チャネルモデルは非常に柔軟で拡張性がありますが、この単純な例では、同じチャネルでメッセージを送受信するだけで十分です。 あなたのメッセージは100ミリ秒以内に世界中のどこにでも配信されます。

PubNubのデプロイメントではサーバーコンポーネントは必要ないので、HTMLとJSで書かれたアプリケーション全体が1つのファイルに含まれています：

```js
<html> <head> <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script> </head> <body> <H1>このコードはプロトコルに依存しないPubNubを使用しています</H1> <form id="input-form"> <label for="message">メッセージを入力してください：</label> <input type="text" id="message" name="message"><br><br> <input type="submit" value="Send"> </form> <div id="messages"></div> <script> var pubnub = new PubNub({ publishKey: 'demo', subscribeKey: 'demo', userId："" + Math.random() }) pubnub.subscribe({ channels: ['ws-channel'] }) pubnub.addListener({ message: payload => { console.log() document.getElementById('messages').innerHTML += 'クライアントからのメッセージ: ' + payload.message + "<br>"; } }) function sendMessage(event) { var inputMessage = document.getElementById('message') pubnub.publish({ channel: 'ws-channel', message: inputMessage.value }) inputMessage.value = "" event.preventDefault(); } document.getElementById('input-form').addEventListener('submit', sendMessage); </script> </body> </html>
```

このコードのライブバージョンは以下で見ることができる。

[https://pubnubdevelopers.github.io/nodejs-websocket-examples/pubnub-client.html](https://pubnubdevelopers.github.io/nodejs-websocket-examples/pubnub-client.html)

![](https://images.ctfassets.net/3prze68gbwl1/75i6TIsSzEevRV2gsusTd1/2e8d9e8e9acba51f103a18a9a6bb27af/pubnub.png)

これですべてです！PubNubを使った開発の詳細については、PubNubの様々な [チュートリアル](https://www.pubnub.com/tutorials/)と [デモ](https://www.pubnub.com/demos/)または [PubNubインタラクティブライブツアー](https://www.pubnub.com/tour/introduction/)をご覧ください。このプラットフォームがどのようにアプリケーションにリアルタイムのインタラクティブ性を提供するかを理解できます。

PubNubはどのようにあなたを助けることができますか？
============================

この記事は[PubNub.comに](https://pubnub.com/blog/nodejs-websocket-programming-examples/)掲載されたものです。

PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるように支援します。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。

PubNubを体験
---------

[ライブツアーを](https://www.pubnub.com/tour/introduction/)チェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する

セットアップ
------

[PubNubアカウントに](https://admin.pubnub.com/signup/)サインアップすると、PubNubキーに無料ですぐにアクセスできます。

始める
---

[PubNubのドキュメントは](https://www.pubnub.com/docs)、ユースケースや[SDKに](https://www.pubnub.com/docs)関係なく、あなたを立ち上げ、実行することができます。