1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ws の「createWebSocketStream」を用いたストリームの処理を Node.js で試す

Posted at

はじめに

Node.js で WebSocketサーバーを作る時などによく使っているのパッケージの「ws」について、情報を見ていて気になった「createWebSocketStream」の話です。

GitHub上で言うと、以下の部分になります。

●websockets/ws: Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
https://github.com/websockets/ws?tab=readme-ov-file#use-the-nodejs-streams-api

image.png

今まで、自分は使ったことがないものだったので、今回軽く試してみました。

実際に試してみる

試す内容について、上記のストリームの処理になりますが、その実装でサーバー側もクライアント側も、両方とも自前で用意する形にしてみます。

上記のサンプルでは、サーバー側は websocket-echo.com というものが指定されているところを、自分で用意した WebSocketサーバーを使う形でやってみます。

下準備

ここから実際に試していきます。下準備はパッケージのインストールのみです。

npm i ws

これで準備は整いました。

コード

ここからコードを準備してみます。

クライアント側

まずはクライアント側です。内容はシンプルに、上記のサンプルの接続先をローカルの自前のサーバーにする、ということだけ対応したものとします。

具体的には以下のとおりで、接続先を ws://localhost:8080 としています。

import WebSocket, { createWebSocketStream } from "ws";

// const ws = new WebSocket('wss://websocket-echo.com/');
const ws = new WebSocket("ws://localhost:8080");

const duplex = createWebSocketStream(ws, { encoding: "utf8" });

duplex.on("error", console.error);

duplex.pipe(process.stdout);
process.stdin.pipe(duplex);

サーバー側

次はサーバー側です。

基本的には、シンプルな WebSocketサーバーに、少しだけ手を加えたような以下になります。

import WebSocket, { WebSocketServer, createWebSocketStream } from "ws";

const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (ws) => {
  const duplex = createWebSocketStream(ws, { encoding: "utf8" });

  duplex.on("error", (err) => {
    console.error("サーバー側ストリームでエラー:", err);
  });

  duplex.pipe(duplex);

  duplex.on("data", (chunk) => {
    console.log("サーバーで受信:", chunk);
  });
});

console.log("WebSocket サーバーをポート 8080 で起動");

ちなみに、以前からよく使っていたシンプルな WebSocketサーバーの処理だと、以下のような実装になります。

import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('error', console.error);

  ws.on('message', function message(data) {
    console.log('received: %s', data);
  });

  ws.send('something');
});

これら 2つの実装の差分としては、WebSocket関連の話では createWebSocketStream(ws, { encoding: "utf8" }); の部分が加わったくらいです。これにより、Node.jsネイティブの双方向ストリームを扱うことができるようです。

双方向ストリームについて

「双方向ストリーム」の duplex は、今回のコードでは createWebSocketStream(ws) を使って得られた「WebSocket をラップした Duplex ストリーム」になります。これは「Readable」と「Writable」の両方の機能を持ったものになるようです。

このため、コード内の duplex.pipe(duplex); というシンプルな記述で、「Readable 部分による WebSocket のメッセージ受信」を「(WebSocket で受信したデータに関しての)Writable 部分による相手への WebSocket での送信」ということが一気にできる形になります。

動作させてみた時の様子

動作させてみた時の様子は以下のとおりです。

流れとしては「サーバー起動」⇒「クライアント実行」⇒「クライアント側から文字を送ると、サーバー側での受信文字列の出力 & クライアント側で文字列の出力(サーバー側に送って返ってきた文字列を受信して出力)」という感じです。

おわりに

今回、ws の情報に出てくる「createWebSocketStream」が気になり、それを用いたストリームの処理を Node.js で試してみました。

今回の内容だと、ありがたみが分かりにくいですが、「Node.js のストリームを扱える」という話について、以下の記事にあるようなメリットを出せる使い方ができそうです(※ 詳細は未確認)。

●Node.js Stream を使ってみる|ラキール公式|株式会社ラキールのエンジニアたちによるTECH BLOG
 https://tech-blog.lakeel.com/n/n62073e6f3101

もう少し、今回の内容は周辺情報なども含め、技術情報を見ていければと思っています

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?