Socket.IOサーバーと、UnityのWebSocketライブラリとでやりとり
はじめに
UnityでSocket.IOとの通信で、UnityのC#のバージョンを変えなきゃいけなかったりして、結構詰まってしまったので、そこらへん変えたくないよって時のメモです
ちなみに前回の記事の続きのような感じで書いてます
前提として、インターネットが使える状況ならばクラウドサービス使ったほうが楽だったりします
環境と使うもの
- Unity 2021.3.6f1
- .NET Standard2.1
- websocket-sharp
- Node.js v16.15.1
- Socket.IO v4.5.1
- express v4.18.1
Socket.IOについて
昔からあるソケット通信をするためのライブラリ
Node.JSでよく使っていて、今はいろいろな言語に対応しているっぽい
概念的には自分の言葉で言うと…「その時に使えるものを使ってリアルタイム通信する」ってことだと思います
Node.JSでソケット通信するために、他にはWebSocketとかよく聞くのであるが、それも包括している感じ
昔だったら例えば、WebSocket使えるブラウザだったら使うけど、対応してないブラウザだったらAjaxを勝手に選んでくれて通信してくれる
もちろん利用する側は使う技術は意識せず、ソースコードを変えずに実装できる
素晴らしい!
Socket.IOとUnity
今はいろいろ言語対応してますが…やはり主に、サーバー側はNode.js
クライアント側はブラウザ
っていう感じ
ですが今回はUnityとで、
公式ドキュメントでは、「.NET」に対応していて、コードは以下に
ですが、.NET6バージョンが必要でした
自分は替えられたと思ったのですが、なんかうまくいがず…
他にも
ここらへんもすんなりいかなかったでした
今回Unity側で使うもの
Socket.IOの特徴として、WebSocketも包括しているということで使ってみました
ちなみに、サーバの通信先がUnityだけならば、Node.js側はWebSocketサーバとして作るほうがシンプルではあります(wsとかWebSocket-Nodeとかを使ったりで)
今回は、前回スマートフォンブラウザとのやりとりを作っていたので、Socket.IOでやってみようと思ってやってみました
ソースコード
サーバ側 Node.js
まだコード全てを理解したわけではないですが…
const fs = require('fs')
const express = require('express');
const app = express();
const https = require('https');
const options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
const server = https.createServer(options, app);
const io = require('socket.io')(server);
const WsServer = require('ws').Server;
const PORT = process.env.PORT || 3000;
const wss = new WsServer({ noServer: true });
server.removeAllListeners("upgrade");
server.on("upgrade", (req, socket, head) => {
console.log('Upgrade!');
wss.handleUpgrade(req, socket, head, (ws) => {
console.log('ws connection!');
ws.on('message', (mess) => {
console.log(mess.toString());
});
ws.on('close', () => {
console.log('ws close');
});
});
});
// --- ブラウザ向け ---
app.use(express.static('public'));
io.on('connection', function(socket){
socket.on('message', function(mess){
console.log(mess);
// 例えば他の接続している端末に配信
io.emit('message', mess);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
// ---
// サーバの立ち上げ
server.listen(PORT, () => {
console.log('listening on https://localhost:' + PORT);
});
クライアント側 Unity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using System.Net.Sockets;
using WebSocketSharp;
public class SocketTest : MonoBehaviour
{
private WebSocket _webSocket;
void Start()
{
Debug.Log("start");
// websocket
_webSocket = new WebSocket("ws://localhost:3000/");
_webSocket.OnOpen += (sender, e) => Debug.Log("WebSocket Open");
_webSocket.OnMessage += (sender, e) => Debug.Log("WebSocket Message Type: " + e.GetType() + ", Data: " + e.Data);
_webSocket.OnError += (sender, e) => Debug.Log("WebSocket Error Message: " + e.Message);
_webSocket.OnClose += (sender, e) => Debug.Log("WebSocket Close");
_webSocket.Connect();
}
void Update()
{
if (Input.GetKeyUp("s"))
{
Debug.Log("send!!");
_webSocket.Send("TestMessage");
}
}
private void OnDestroy()
{
_webSocket.Close();
_webSocket = null;
}
}
Discussion