この投稿は、nodejsのwsとブラウザapiのWebSocketについて、自分の勉強のためにドキュメントを読みながら試しただけのものになります。
なのでWebSocketについての詳細な情報が欲しい方は、以下のリンクを見て、本記事は読まなくて良いです
- GitHub - websockets/ws: Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
- WebSocket - Web APIs | MDN
wsのAPIドキュメントは↓のようです
間違っているなどあればご指摘お願いします
WebSocket仕様関連
ブラウザ対応状況
多くのブラウザでサポートされています
イベントリスナー
WebSocket
apiは以下の4つのイベントを持っています
<!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>
<button id="btn">Hello</button>
<script>
const sock = new WebSocket("ws://127.0.0.1:5001");
sock.addEventListener("open", e => {
console.log("接続が開かれたときに呼び出されるイベント");
});
sock.addEventListener("message", e => {
console.log("サーバーからメッセージを受信したときに呼び出されるイベント");
});
sock.addEventListener("close", e => {
console.log("接続が閉じられたときに呼び出されるイベント");
});
sock.addEventListener("error", e => {
console.log("エラーが発生したときに呼び出されるイベント");
});
btn.addEventListener("click", e => {
sock.send("hello");
});
</script>
</body>
</html>
WebSocketのサーバを動作させる
npm init -y
npm i -D ws
{
"name": "01_sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"ws": "^6.1.4"
}
}
const server = require("ws").Server;
const s = new server({ port: 5001 });
s.on("connection", ws => {
ws.on("message", message => {
console.log("Received: " + message);
if (message === "hello") {
ws.send("hello from server");
}
});
});
node index.js
open、messageイベントの確認
イベント起こしやすいようにボタンを追加しました
<button id="btn">Hello</button>
<script>
const sock = new WebSocket("ws://127.0.0.1:5001");
sock.addEventListener("open", e => {
console.log("接続が開かれたときに呼び出されるイベント");
});
sock.addEventListener("message", e => {
console.log("サーバーからメッセージを受信したときに呼び出されるイベント");
});
sock.addEventListener("close", e => {
console.log("接続が閉じられたときに呼び出されるイベント");
});
sock.addEventListener("error", e => {
console.log("エラーが発生したときに呼び出されるイベント");
});
btn.addEventListener("click", e => {
sock.send("hello");
});
</script>
接続された時、サーバーからメッセージを受信した時にそれぞれイベントが実行されています
messageイベントはe.data
からサーバーからの受信内容を受け取ることができます
sock.addEventListener("message", e => {
console.log(e.data);
});
NetworkタブのWS
からでもメッセージの内容を見ることができます。
- 緑の矢印が送信したデータ
- 赤の矢印がサーバーから受信したデータです
close、errorイベントの確認
ws.close()
を実行すると、closeイベントが実行されるのが確認できました、
また、サーバーを停止した状態で接続しに行くと、エラーイベントが実行されるのも確認できました。
サーバー側で接続が切れた場合の処理
const server = require("ws").Server;
const s = new server({ port: 5001 });
s.on("connection", ws => {
ws.on("message", message => {
ws.send("hello from server");
});
// 接続が切れた場合
ws.on('close', () => {
console.log('I lost a client');
});
});
複数のクライアントにデータ送信する
const server = require("ws").Server;
const s = new server({ port: 5001 });
s.on("connection", ws => {
ws.on('message', message => {
ws.send("送信してきたクライアントのみに返す");
s.clients.forEach(client => {
client.send('接続しているクライアント全てに送信');
});
s.clients.forEach(client => {
if (client !== ws)
client.send('接続している自分以外のクライアント全てに送信');
});
});
});
複数データの送受信
オブジェクトをJSON.stringify()
とする
const sock = new WebSocket("ws://127.0.0.1:5001");
sock.addEventListener("message", e => {
// サーバーから受信
const { hoge, fuga, piyo } = JSON.parse(e.data);
console.log(hoge, fuga, piyo);
});
btn.addEventListener("click", e => {
// サーバーへ送信
sock.send(JSON.stringify({
name: 'alice',
age: 25,
}));
});
const server = require("ws").Server;
const s = new server({ port: 5001 });
s.on("connection", ws => {
ws.on('message', message => {
// クライアントから受信
const { name, age } = JSON.parse(message);
console.log(name, age);
// クライアントへ送信
ws.send(JSON.stringify({
hoge: true,
fuga: [1, 3, 5],
piyo: 0.5,
}));
});
});
urlを確認する
WebSocket.url
で取得できる
接続状態を確認する
接続状態の定数が用意されています
Constant | Value |
---|---|
WebSocket.CONNECTING | 0 |
WebSocket.OPEN | 1 |
WebSocket.CLOSING | 2 |
WebSocket.CLOSED | 3 |
readyState
から現在の接続状態を取得できました
const sock = new WebSocket("ws://127.0.0.1:5001");
console.log(`readyState:${sock.readyState}`);
sock.addEventListener("open", e => {
console.log(`readyState:${sock.readyState}`);
});
sock.addEventListener("close", e => {
console.log(`readyState:${sock.readyState}`);
});
最後まで読んでいただいてありがとうございました