wsモジュール

wsモジュールは、WebSocketプロトコル(RFC-6455に準拠する)の実装ライブラリです。
socket.ioのように多機能ではありませんが、シンプルな作りで非常に高速に動作するのが特徴です。
※socket.ioも内部でwsを使用しています

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.4
  • Node.js : v0.8.15
  • npm : 1.1.66

適当なディレクトリを作成し、そこでnpmを使用して必要モジュールをインストールします。
今回はexpressも使用するので、いっしょにインストールしましょう。

1
2
3
% mkdir ws
% cd ws
% npm install ws express

wsモジュールを使ったチャット- server:nodejs & client:html

ありふれた例ですが、wsモジュールとexpressモジュールを使用してシンプルなチャットをつくってみましょう。
まずはサーバ側のモジュールをapp.jsという名前で作成します。

1
2
3
4
5
6
7
8
9
//app.js
var WebSocketServer = require('ws').Server
    , http = require('http')
    , express = require('express')
    , app = express();
 
app.use(express.static(__dirname + '/'));
var server = http.createServer(app);
var wss = new WebSocketServer({server:server});
cs

expressモジュールからHttpサーバを作成し、wsモジュールのServerの引数にしてWebSocket用サーバオブジェクトを作成します。

WebSocketの接続を保存しておく変数、connectionsを用意しておきます。
WebSocketServerのonメソッドを使用し、接続時、切断時、メッセージ受信時の処理を記述します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var connections = [];
 
wss.on('connection'function (ws,req) { //wss.on('connection'...)은 웹소켓을 연결하는 ws와 클라이언트 쪽의 데이터를 담고 있는 req를 콜백으로 반환한다.
    connections.push(ws);
    ws.on('close'function () {
        connections = connections.filter(function (conn, i) {
            return (conn === ws) ? false : true;
        });
    });
    ws.on('message'function (message) {
        console.log('message:', message);
        broadcast(JSON.stringify(message));
    });
});
cs

なお、接続時にはconnections変数へ接続オブジェクトを保存し、切断時にはconnections変数から削除します。
broadcastはこの後定義する関数です。

wsモジュールには、Websocketで接続しているユーザー全員にブロードキャストする機能はありません。
接続時に保存している配列を精査して全員にsendメソッドでメッセージを送ります。

1
2
3
4
5
6
7
8
function broadcast(message) {
    connections.forEach(function (con, i) {
        con.send(message);
    });
};
 
server.listen(3000);
 
cs

最後に3000番ポートでサーバを起動しています。

app.js全文です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//app.js
var WebSocketServer = require('ws').Server
    , http = require('http')
    , express = require('express')
    , app = express();
 
app.use(express.static(__dirname + '/'));
var server = http.createServer(app);
var wss = new WebSocketServer({server:server});
 
//Websocket接続を保存しておく
var connections = [];
 
//接続時
wss.on('connection'function (ws) {
    //配列にWebSocket接続を保存
    connections.push(ws);
    //切断時
    ws.on('close'function () {
        connections = connections.filter(function (conn, i) {
            return (conn === ws) ? false : true;
        });
    });
    //メッセージ送信時
    ws.on('message'function (message) {
        console.log('message:', message);
        broadcast(JSON.stringify(message));
    });
});
 
//ブロードキャストを行う
function broadcast(message) {
    connections.forEach(function (con, i) {
        con.send(message);
    });
};
 
server.listen(3000);
cs

次はindex.htmlファイルです。
sendボタンを押すと、テキストフィールドの文字をブロードキャストします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
<head>
    <script>
        function send() {
            ws.send(document.getElementById('msg').value);
        }
 
        var host = window.document.location.host.replace(/:.*/'');
        var ws = new WebSocket('ws://' + host + ':3000');
        ws.onmessage = function (event) {
            document.getElementById("messages").innerHTML += "<div>" + JSON.parse(event.data) + "</div>";
            console.log(JSON.parse(event.data));
        };
    </script>
</head>
<body>
<strong>ws chat</strong><br>
<input type="text" id="msg"/>
<input type="button" value="send" onclick="send()"/>
<br>
<hr>
<div id="messages"/>
</body>
</html>
cs


サーバを起動し、ブラウザでhttp://localhost:3000/index.htmlを複数ブラウザで開いた後、文字を送信してみてください。

チャットができてますね。

1
% node app.js


5分で動かせるWebsocket

https://qiita.com/okumurakengo/items/a8ccea065f5659d1a1de


wsモジュールを使ったチャット- server:nodejs & client:nodejs





server-side.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
let WebSocketServer = require('ws').Server
    , http = require('http')
    , express = require('express')
    , app = express();
 
 
let server = http.createServer(app);
let wss = new WebSocketServer({server:server});
 
 
wss.on('connection'function(ws) {
 
    // When connection is success
    console.dir('connection on');
    console.log('Data sending from server to client started');
    _sendDataTimeGap(ws);
 
    // Processing data from client socket
    ws.on('message'function(message) {
        console.log(' message from client : ', message);
    });
    ws.on('error',function(error){
        console.log('error from client : ',error);
    });
    ws.on('close',function(code,reason){
        console.log('close from client : ',`code:${code}`,` reason:${reason}`);
    });
 
    // ws.close();
});
 
server.listen(3000);
 
 
/**
 * Function
 * @params {filePath:string} path of uploaded image file
 * @params {langs:array} array of langs from front
 */
 
function _sendDataTimeGap(ws){
    setTimeout(function() {
        ws.send('Server said Hello, Client' + new Date());
    }, 2000);
}
cs


client-side

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
const fs = require('fs');
const WebSocket = require('ws');
 
var ws = new WebSocket('ws://localhost:3000');
 
// When connection is success
ws.on('open'function() {
    console.log('socket connected');
    console.log('Data sending from client to server started');
    _sendDataTimeGap(ws);
});
 
// Processing data from server socket
ws.on('close'function close(e) {
    console.log('close from server : ',e);
});
 
ws.on('message'function message(e) {
    console.log('message from server : ', e);
});
 
ws.on('error'function error(e) {
    console.log('error from server :',e);
});
 
 
/**
 * Function
 * @params {filePath:string} path of uploaded image file
 * @params {langs:array} array of langs from front
 */
 
function _sendDataTimeGap(ws){
    setTimeout(function() {
        ws.send('Client said Hello, Server' + new Date());
    }, 2000);
}
cs




https://www.npmjs.com/package/ws

まとめ

node.jsでWebSocketを使いたい場合、ほとんどのケースでsocket.ioを使用しているのではないでしょうか。
しかし、socket.ioほどの機能は必要なかったり(ブロードキャスト機能もありませんが・・・)、
wsをベースにしてライブラリを作成する場合には直接使用することもあるかもしれません。



参考サイトなど

+ Recent posts