初めに
UnityでWebSoketを使って通信をするのはいろいろ大変なので、どのライブラリを使おうかと調べていましたが、以下のライブラリを見つけたので動かしてみます
サーバーのコードは以下のリポジトリで公開しています
開発環境
準備
Python側で以下のライブラリを使用するためインストールを行います
pip install websockets
簡単な接続確認
まずは 接続確認から行っていきます
Unity
using UnityEngine; using System.Collections; using MikeSchweitzer.WebSocket; public class WebSocketTester : MonoBehaviour { public WebSocketConnection _connection; private string _url = "ws://localhost:8765"; // Pythonサーバーのアドレス private void Start() { // WebSocketの初期化と接続 _connection = gameObject.AddComponent<WebSocketConnection>(); _connection.DesiredConfig = new WebSocketConfig { Url = _url }; _connection.Connect(); // 接続状態の変更イベント _connection.StateChanged += OnStateChanged; // メッセージ受信イベント _connection.MessageReceived += OnMessageReceived; // エラーメッセージ _connection.ErrorMessageReceived += OnErrorMessageReceived; } private void OnStateChanged(WebSocketConnection connection, WebSocketState oldState, WebSocketState newState) { Debug.Log($"WebSocket state changed from {oldState} to {newState}"); // 接続が確立された場合 if (newState == WebSocketState.Connected) { // サーバーへメッセージを送信 SendMessageToServer("Hello from Unity"); } } private void OnMessageReceived(WebSocketConnection connection, WebSocketMessage message) { Debug.Log($"Message received from server: {message.String}"); } private void OnErrorMessageReceived(WebSocketConnection connection, string errorMessage) { Debug.LogError($"WebSocket error: {errorMessage}"); } private void SendMessageToServer(string message) { if (_connection != null && _connection.State == WebSocketState.Connected) { _connection.AddOutgoingMessage(message); Debug.Log($"Message sent to server: {message}"); } } private void OnDestroy() { if (_connection != null) { _connection.Disconnect(); _connection = null; } } }
Python
import asyncio import websockets async def echo(websocket, path): async for message in websocket: print(f"Received message: {message}") await websocket.send(f"Echo: {message}") start_server = websockets.serve(echo, "localhost", 8765) asyncio.get_event_loop().run_until_complete(start_server) print("WebSocket server started on ws://localhost:8765") asyncio.get_event_loop().run_forever()
実行をすると以下のようなログが表示されます
クライアントから定期的にメッセージを送信
次にクライアントから定期的にメッセージを送るような少し複雑な?ことをします (サーバーのコードは同じものです)
using System; using UnityEngine; using Cysharp.Threading.Tasks; using System.Threading; using MikeSchweitzer.WebSocket; using Random = UnityEngine.Random; public class WebSoketTest : MonoBehaviour { public WebSocketConnection _connection; private string _url = "ws://localhost:8765"; // Pythonサーバーのアドレス private bool _shouldReconnect = true; private CancellationTokenSource _cts; private void Start() { _cts = new CancellationTokenSource(); // WebSocketの初期化と接続 _connection = gameObject.AddComponent<WebSocketConnection>(); _connection.DesiredConfig = new WebSocketConfig { Url = _url }; _connection.Connect(); // 接続状態の変更イベント _connection.StateChanged += OnStateChanged; // メッセージ受信イベント _connection.MessageReceived += OnMessageReceived; // エラーメッセージ _connection.ErrorMessageReceived += OnErrorMessageReceived; // 定期的なメッセージ送信を非同期タスクで実行 SendMessagesPeriodically(_cts.Token).Forget(); } private void OnStateChanged(WebSocketConnection connection, WebSocketState oldState, WebSocketState newState) { Debug.Log($"WebSocket state changed from {oldState} to {newState}"); // 再接続の試み if (newState == WebSocketState.Disconnected && _shouldReconnect) { Reconnect().Forget(); } } private void OnMessageReceived(WebSocketConnection connection, WebSocketMessage message) { Debug.Log($"Message received from server: {message.String}"); } private void OnErrorMessageReceived(WebSocketConnection connection, string errorMessage) { Debug.LogError($"WebSocket error: {errorMessage}"); } private async UniTaskVoid SendMessagesPeriodically(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { if (_connection != null && _connection.State == WebSocketState.Connected) { var message = "Random message: " + Random.Range(0, 1000); _connection.AddOutgoingMessage(message); Debug.Log($"Message sent to server: {message}"); } // 送信間隔を待機 await UniTask.Delay(TimeSpan.FromSeconds(5), cancellationToken: cancellationToken); } } private async UniTaskVoid Reconnect() { Debug.Log("Attempting to reconnect..."); await UniTask.Delay(TimeSpan.FromSeconds(5)); if (_connection != null && _connection.State != WebSocketState.Connected) { _connection.Connect(); } } private void OnDestroy() { _cts.Cancel(); _cts.Dispose(); _shouldReconnect = false; if (_connection != null) { _connection.Disconnect(); _connection = null; } } }
ここでは以下のようなメッセージが表示されます