node.jsなんかでオンラインなゲームを作る(5) ルーム機能(socket.io)

author potpro(ぼとぷろ)
2015/04/15

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した時の処理、などでログを表示するようにします。

(game

まあ、ゲームの道のりは遠い。

githubにソースがあります。