Edited at

Express×socket.ioを使ってwebsocketで遊ぼう~第1話~

More than 1 year has passed since last update.

参考にしていただければ幸いですが、参考にして不具合等が起きた場合、保障はできませんのであしからず。

間違い等あればご教授いただけると助かります。

>> 追記(2017/07/20)
nodejs, npm のインスコ方法を記載しました。
(epelからyumインスコすると、バージョンv0.10が入るので・・・)


この回のゴール

・websocket通信をsocket.ioとExpressを使用して実装

・送信したデータの共有


環境

Windows7

Node.js v0.10.25

* 検証環境

Opera 32

Chrome 46

FireFox 41

IE 9(検証のためにダウングレードしてた・・・)


Node.jsのインスコ

windowsの場合は本家から落とすだけです。

コマンドプロンプト上で「node -v」と打って、バージョンが表示されればOK。

 されなければ、環境変数に追加してやってください。

CentOSの場合は下記コマンドを打ってください。

※CentOS6以外の場合は一行目のepelリポジトリの参照元を変えてください

$ rpm -ivh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

$ curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
$ yum install -y gcc gcc-c++ nodejs


ベースプロジェクトの作成

 Express とは・・・

  Node.js用のフレームワーク


Expressのインスコ

sudo npm install -g express-generator

-g でグローバルにインストールします。

express コマンドが使用できればokです。


作業フォルダを作成

以下のような構成でフォルダを3つ用意します


フォルダ構成

socketTest

├━ socket
└━ chat

socketフォルダ:websocketのサーバーとします

chatフォルダ:実際にチャットを行うHTMLを設置します


socketサーバーを構築


Expressフレームワークを設置


shell

$ cd socketTest/socket

$ express # expressのテンプレ構築
$ npm install # 必要なパッケージのインスコ
$ npm install socket.io # package.jsonに記述してもOKです


socket.ioを扱うための準備


shell

$ mkdir routes/module

$ touch mod_socket.js

上のコマンドで作成した「mod_socket.js」というファイルにwebsocket起動用のスクリプトを書いていきます。


socketTest/socket/routes/module/mod_socket.js

var http = require('http');

//サーバインスタンス作成
var server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type':'text/html'});
res.end('server connected');
});
var io = require('socket.io').listen(server);

server.listen(8888);//8888番ポートで起動

//接続確立時の処理
io.sockets.on('connection', function (socket) {
// この中でデータのやり取りを行う
console.log('connected');
});


app.js内で「mod_socket/js」というファイルを読み込むようにします。

上部のvar群の一番下に追加する形でいいかもですね。


socketTest/socket/app.js

// socket

var socket = require('./routes/module/mod_socket.js');


Nodeサーバーの起動

ここまで来たら、Expressが動作するか確認してみましょう。

Express自体はデフォルト3000番ポートになります。

websocket自体は指定したとおり8888番を用意しているので、下記のように確認してみます。


shell

$ pwd

***/socketTest/socket
$ npm start

npm start で起動

ctrl + c で終了です。たまに、終了に時間がかかります

Expressとsocket.ioの確認

http://localhost:3000

express.png

Expressの初期ページが表示されています。

http://localhost:8888/socket.io/socket.io.js

websocket通信用にsocket.ioで自動生成されるjsファイルです。


外部のHTMLからwebsocket通信


フォルダ構成

socketTest

├━ socket # wsサーバー
└━ chat # こっちを使います


socketTest/chat/index.html

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>チャットルーム</title>
<!-- /* socket.ioのjsを読み込む */ -->
<script type="text/javascript" src="http://localhost:8888/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket;
(function(){
// socket通信が開始される
socket = io.connect("http://localhost:8888");
})();
</script>
</head>
<body>

</body>
</html>


成功すれば、シェルの方に「connected」というメッセージが出ていると思います。

(画像では4ブラウザで開いていたのでその分ログが出ています)

express-shell.png

これは、「socketTest/socket/routes/module/mod_socket.js」に記述したconsole.logの内容になります。

(一応JSなのでconsole.logでのデバッグが可能です)

外部からwebsocket通信に接続されると、mod_socket.jsファイルの connection を通過します。

この connection はsocket.ioのデフォルトで用意されているものになります。


外部のHTMLからメッセージを送る

@ポイント

・データの送信にはemit、受信にはonというファンクションを使用します。

・送受信するデータはJSON形式ですが、送信時はJSON.stringifyを使って文字列形式に変換

 受信時はJSON.parseを使ってJSON形式に変換してやり取りをする


socketTest/socket/routes/module/mod_socket.js(L:11)

  //接続確立時の処理

io.sockets.on('connection', function (socket) {
// この中でデータのやり取りを行う
// 「message」という名前で受信したデータはこの中を通る
socket.on('message', function(d){
// そのまま全接続先へ送信
io.emit('receiveMessage', d);
});
});


socketTest/chat/index.html[body内]

<body>

<div>
<textarea id="message" rows="4" cols="40"></textarea>
<button type="button" id="send">Send</button>
</div>
<div>
<ul id="messageList"></ul>
</div>
</body>


socketTest/chat/index.html[2つ目のscript内]

    var socket, emit;

(function(){
socket = io.connect("http://localhost:8888");
emit = function (name, data){
// json → 文字列に変換して送信する関数
socket.emit(name, JSON.stringify(data));
}
})();
window.onload = function(){
var sendBtn = document.getElementById('send');
var message = document.getElementById('message');
sendBtn.addEventListener("click", function(){
emit('message', {text: message.value});
});
socket.on('receiveMessage', function(d){
var data = JSON.parse(d), // 文字列→JSON
li = document.createElement('li'), // liタグ作成
list = document.getElementById('messageList'); // ulタグの取得
li.textContent = data.text; // liタグに値を入れる
list.appendChild(li); // ulタグの子ノードとして作成したliタグを追加
});
};

複数ブラウザで立ち上げて、メッセージを送信するとそれぞれの画面に送信したメッセージが

どんどん表示されていくと思います。

express-2.png

今回はひとまずここまでです。