Unity 实现socket通信
实现双向通信,和断线重连
需求场景:有A、B两个unity项目,需要A控制B播放对应的视频。(A点击某按钮,B播放对应的视频)
-
服务端
- 我这边服务端挂载在B项目,随便创建个空物体挂载脚本即可。脚本如下
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using UnityEngine; using System.Collections; using System.Threading; public class SocketServer : MonoBehaviour { private GuidePageController _PlayerManager; private TcpListener listener; private TcpClient client; private NetworkStream stream; private SynchronizationContext unityContext; [Range(1,65535)][Header("socket通信端口")] public int port; void Start() { unityContext = SynchronizationContext.Current; _PlayerManager = GetComponent<GuidePageController>(); StartServer(); } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { GetComponent<SocketServer>().SendWebSocketMessage("Hello from B!"); } } void StartServer() { Debug.Log($"Socket Server will start on port {port}"); listener = new TcpListener(IPAddress.Any, port); listener.Start(); Debug.Log($"Socket Server started on port {port}"); Task.Run(() => AcceptClient()); } async void AcceptClient() { client = await listener.AcceptTcpClientAsync(); Debug.Log("Client connected"); stream = client.GetStream(); await Task.Run(() => ReceiveMessages()); } async Task ReceiveMessages() { byte[] buffer = new byte[1024]; while (client.Connected) { int byteCount = await stream.ReadAsync(buffer, 0, buffer.Length); if (byteCount > 0) { string message = Encoding.UTF8.GetString(buffer, 0, byteCount); Debug.Log("Command received: " + message); try { Debug.LogError(unityContext); unityContext.Post(_ => _PlayerManager.SwitchPages(message.Trim()), null); } catch (Exception ex) { Debug.LogError("Error receiving message: " + ex.Message); } } else { Debug.Log("Connection lost."); Task.Run(() => AcceptClient()); // 尝试重新开始监听 break; } } } public async void SendWebSocketMessage(string message) { if (client != null && client.Connected) { byte[] buffer = Encoding.UTF8.GetBytes(message); await stream.WriteAsync(buffer, 0, buffer.Length); Debug.Log("Sent: " + message); } } void OnDestroy() { CloseConnection(); } private void CloseConnection() { listener?.Stop(); if (client != null) { client.Close(); client = null; } if (stream != null) { stream.Close(); stream = null; } } }
- 这段代码为接收消息后进行的操作,自定义即可
_PlayerManager.SwitchPages(message.Trim()
-
客户端
- 客户端挂载在A项目
using System; using System.Collections.Generic; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using UnityEngine; public class SocketClient : MonoBehaviour { [Header("Socket连接的IP及端口")] public string Address; public int Port; private TcpClient client; private NetworkStream stream; private int _waitTime = 5000; private SocketClient _socketClient; private Dictionary<KeyCode, string> _keyMap; void Start() { _socketClient = GetComponent<SocketClient>(); ConnectToServer(); _keyMap = new Dictionary<KeyCode, string> { { KeyCode.Alpha1, "1" }, { KeyCode.Alpha2, "2" }, { KeyCode.Alpha3, "3" }, { KeyCode.Alpha4, "4" }, { KeyCode.Alpha5, "5" }, { KeyCode.Alpha6, "6" }, { KeyCode.Alpha7, "7" }, { KeyCode.Alpha8, "8" }, { KeyCode.Alpha9, "9" }, { KeyCode.Alpha0, "0" }, { KeyCode.Space, "space" }, { KeyCode.LeftArrow, "left arrow" }, { KeyCode.RightArrow, "right arrow" } }; } void Update() { foreach (var keyCode in _keyMap.Keys) { if (Input.GetKeyDown(keyCode)) { string keyString = _keyMap[keyCode]; _socketClient.SendWebSocketMessage(keyString); break; } } } async Task ConnectToServer() { Debug.Log("尝试建立通信"); try { client = new TcpClient(); await client.ConnectAsync(Address, Port); // 连接到B项目的服务器 Debug.Log("Connected to server"); stream = client.GetStream(); // 开始监听消息 _ = Task.Run(() => ReceiveMessages()); } catch (Exception ex) { Debug.LogError("Error connecting to server: " + ex.Message); await Task.Delay(_waitTime); await ConnectToServer(); } } async void ReceiveMessages() { byte[] buffer = new byte[1024]; while (client.Connected) { int byteCount = await stream.ReadAsync(buffer, 0, buffer.Length); if (byteCount > 0) { string message = Encoding.UTF8.GetString(buffer, 0, byteCount); Debug.Log("Received: " + message); // 根据接收到的消息进行不同的处理 } else { print("--------通信中断--------"); CloseConnection(); await Task.Delay(_waitTime); // 等待后再开始重连 await ConnectToServer(); break; } } } public async void SendWebSocketMessage(string message) { if (client != null && client.Connected) { byte[] buffer = Encoding.UTF8.GetBytes(message); await stream.WriteAsync(buffer, 0, buffer.Length); Debug.Log("Sent: " + message); } } void OnDestroy() { CloseConnection(); } private void CloseConnection() { if (client != null) { client.Close(); client = null; } if (stream != null) { stream.Close(); stream = null; } } }
- 使用A向B发送消息
FindFirstObjectByType<SocketClient>().SendWebSocketMessage("111111");
附图一张