potpro (ぽとぷろ)
Full-stuck engineer(Not Full-stack)
JS/PHP/Go/Docker/Nginxなど。技術または趣味寄りの発信ブログです。
全 85 記事node.jsなんかでオンラインなゲームを作る(5) ルーム機能(socket.io)
node.jsなんかでオンラインなゲームを作る(5) ルーム機能(socket.io)
Websocketを利用して、特定の処理や通知などをそのルーム、またはその人にだけ行う。
WebSocket - Wikipedia Websocketは双方向通信のプロトコルです。
html5と対応ブラウザなら動作します。 双方向通信なので、つまりは、サーバ側からクライアントにプッシュ通知、クライアントからサーバ側にデータ送信、といったことが可能になります。
connectionが成立した後は後ろでプロトコルが動いてくれますので、動的なWebサイトとして、しかもサーバとのやり取りをずっと行えます。
この技術を応用すれば、オンラインゲームに必須なチャット機能的なこと、ダメージ処理とかそういうの、が全部ブラウザ上で動くってことですね。
Ajax(XMLHttpRequest)なんかだとクライアントから問い合わせは出来てもサーバから受け取ることは難しいので、Ajaxの上位互換みたいな感じらしいです。 socket.ioは、Websocketを使うためのnode.jsモジュールです。
まずは、初期設定的な何か。
サーバ(app.js)
socketio = require('socket.io')
var server = http.createServer(app);
var io = socketio.listen(server);
これで、websocketプロトコルをlistenします。
一応独自プロトコルなのですがTCP 80/443で動作しますので、そのままhttp(TCP 80)に乗っける形になるのでこう書きます。
クライアント(main.js)
var socket = io.connect();
クライアントは、事前にhtmlから/socket.io/socket.io.js
をロードして使用します。 (socket.ioサーバーを立てた段階で、自動的にサイトからロードできるようになります) 前回作成したejsに書いておきます。
そうすれば、この一行を書くだけで使えるようになります。
socket.ioは、socket.emit(送信する値)で送信、socket.onで受け取りの処理(callback)大体この二つを使います。 socket.ioでのROOM処理は、この辺を参照。
既にjoinメゾットというのが準備されていて、同じ部屋にjoinしたクライアントだけ、emit(送る)ことが出来ます。 参考:
順を追って書いていくと、 クライアントが接続するので、その接続をサーバ側が受け取り、サーバ側はRoomIDにしたがってjoinメゾットで部屋を振り分けます。 その後、to(room).emitメゾットでその部屋のみ送ります。
クライアント(main.js)
socket.on('connected', function() {
//部屋番号送信・初期表示
socket.emit('init', {'room': RoomID});
});
//文章受け取り
socket.on("logmessage", function (data) {
logpush(data); //dataを文章を表示する関数
});
s.on('connected',\[callback\])はWebsocket接続完了時に自動的に呼び出されます。それに、RoomIDをinitとしてサーバに送信。 **サーバ(app.js)**
var chat = io.sockets.on('connection', function(socket) {
socket.emit('connected');
console.log(socket.id+" connected");
//room別に管理
socket.on("init",function(req){
//join(room)で部屋を作る
socket.setRoominfo=req.room;
socket.join(req.room); //roomIDごとに登録
socket.join(socket.id); //個別に識別するためにクライアント識別子であるsocketidを登録
console.log(req.room+" join");
});
socket.on('msg post', function(msg) { //Room内にメッセージ送信
chat.to(socket.setRoominfo).emit("logmessage", msg);
});
});
簡単なチャットとしての機能が出来ました。 socket.setRoominfoに、一時的なデータを格納するためRoomIDを入れています。 これで、各クライアントが'msg post'と文字列をemitすると、同じルームに入っているクライアント全てに表示されます。 その後、Disconnection(ブラウザから離れた時)の処理、gameをstartした時の処理、などでログを表示するようにします。
(
まあ、ゲームの道のりは遠い。
githubにソースがあります。