UnityでSocket.IOの1.x系を使う

最終更新日:2015年07月19日

UnityでSocket.IOを使う方法を調べてみたところ、0.9系の情報がほとんどのようなんですが、unity-socket.ioというライブラリが1.x系に対応していたので使ってみました。最低限動いているらしいというメモとコード断片です。簡単に試した限りでは、iOSとAndroidでも特に変更なしで動くようです。ただし、namespaceやroom、バイナリデータには対応していません。

執筆時の環境はUnity 5.1.2、Node v0.12.7、Socket.IO 1.3.6です。

Unityのクライアント

unity-socket.ioのSocketIOフォルダをUnityのAssetsフォルダにコピーして、ScenesのScoketIOTestシーンを開きます。HierarchyのSocketIOオブジェクトを選択して、インスペクタでサーバのURLを設定します。

TestSocketオブジェクトにサンプルコードが入っていますので、これを参考にメッセージの送受信をしてみました。

using UnityEngine;
using SocketIO;

public class SocketIOTest : MonoBehaviour
{
    SocketIOComponent socket;

    public void Start() 
    {
        GameObject go = GameObject.Find("SocketIO");
        socket = go.GetComponent<SocketIOComponent>();

        socket.On("online", OnOnline);
        socket.On("offline", OnOffline);

        socket.On("message", OnMessage);
    }

    public void OnOnline(SocketIOEvent e)
    {
        string id = e.data.GetField("id").str;

        Debug.Log("online id: " + id);
    }

    public void OnOffline(SocketIOEvent e)
    {
        string id = e.data.GetField("id").str;

        Debug.Log("offline id: " + id);
    }

    public void OnMessage(SocketIOEvent e)
    {
        JSONObject obj = e.data;

        string id = obj.GetField("id").str;
        string message = obj.GetField("message").str;

        Debug.Log("message id: " + id + " message: " + message);
    }

    public void EmitMessage(string message)
    {
        JSONObject jsonObject = new JSONObject(JSONObject.Type.OBJECT);
        jsonObject.AddField("message", message);

        socket.Emit("message", jsonObject);
    }
}

イベントのパラメータはJSONオブジェクトのみのようです。文字列などを受信すると、例外が発生して切断・再接続を繰り返したりするようなので注意です。

Node.jsのサーバ

普通にnpm install socket.ioして、こんな感じのを動かしてみます。

var io = require("socket.io")();

io.on("connection", function (socket) {
    console.log("online id: " + socket.id);
    socket.broadcast.emit("online", { id: socket.id });
    
    socket.on("disconnect", function () {
        console.log("offline id: " + socket.id);
        socket.broadcast.emit("offline", { id: socket.id });
    });
    
    socket.on("message", function (obj) {
        var id = socket.id;
        var message = obj.message;
        
        console.log("message id: " + id + " message: " + message);
        io.emit("message", { id: id, message: message });
    });

});

io.listen(4567);

ブラウザのクライアント

適当にJavaScriptコードのみを載せます。

// <script src="https://cdn.socket.io/socket.io-1.3.6.js"></script>

let socket = io.connect("http://localhost:4567/");

socket.on("connect", function () {
    let id = socket.io.engine.id;
    println("Connected ID: " + id);
});

socket.on("message", function (obj) {
    println("message id: " + obj.id + " message: " + obj.message);
});

socket.on("online", function (obj) {
    println("online id: " + obj.id);
});

socket.on("offline", function (obj) {
    println("offline id: " + obj.id);
});

function send() {
    var message = document.getElementById("message").value;
    socket.emit("message", { message: message });
    
    document.getElementById("message").value = "";
}

function println(message) {
    document.getElementById("messages").innerHTML += message + "<br>";
}

// export
window.send = send;

こんな感じでとりあえずUnityとブラウザ間の通信ができました。

ハマったこと

バカバカしいことですが、「Unityはウィンドウのフォーカスがはずれると一時停止する」というのを忘れていてはまりました。ブラウザのクライアントから必死でイベントを送っていて、なんで反応しないんだとか1時間くらい言ってました……。Unityをアクティブにするとイベントが受信され、コンソールウィンドウが更新されます。

書いた人:こりん(@k0rin
VR開発メモトップ