From 18e418ca0b5354d464f242be08958b90ee8d779a Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期五, 06 二月 2026 14:59:24 +0800
Subject: [PATCH] TCP/WEBSOCKET SUPPORT
---
Main/Core/NetworkPackage/Socket/ClientSocket.cs | 397 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 324 insertions(+), 73 deletions(-)
diff --git a/Main/Core/NetworkPackage/Socket/ClientSocket.cs b/Main/Core/NetworkPackage/Socket/ClientSocket.cs
index 3055fe0..bf072a0 100644
--- a/Main/Core/NetworkPackage/Socket/ClientSocket.cs
+++ b/Main/Core/NetworkPackage/Socket/ClientSocket.cs
@@ -1,39 +1,73 @@
锘縰sing UnityEngine;
using System;
-using System.Collections;
using System.Collections.Generic;
+
+#if !UNITY_WEBGL && !H5_VERSION
using System.Net;
using System.Net.Sockets;
using System.Threading;
+#else
+using NativeWebSocket;
+using Cysharp.Threading.Tasks;
+#endif
+/// <summary>
+/// 缁熶竴鐨勭綉缁淪ocket绫� - 鑷姩閫傞厤TCP Socket鍜學ebSocket
+/// TCP Socket: Windows, Mac, iOS, Android绛夊钩鍙�
+/// WebSocket: WebGL/寰俊灏忔父鎴忕瓑Web骞冲彴
+/// </summary>
public class ClientSocket
{
GameNetEncode encoder = new GameNetEncode();
+
+#if !UNITY_WEBGL && !H5_VERSION
+ // TCP Socket 瀹炵幇锛堥潪WebGL骞冲彴锛�
Socket m_Socket;
public Socket socket { get { return m_Socket; } }
-
private Thread m_packageThread;
- private byte[] bufferBytes = new byte[4096]; // 4K锛屽崟鍖呭瓧鑺傛暟缁勭紦瀛�
- private byte[] fragmentBytes; //鐣欏寘鍚庣殑鍐呭
- private long getBytesTotal = 0; //鍙戦�佺殑鏁版嵁鎬婚噺
- private long sendBytesTotal = 0; //鍙戦�佺殑鏁版嵁鎬婚噺
+ private byte[] bufferBytes = new byte[4096];
+ private byte[] fragmentBytes; // TCP鍒嗗寘缂撳瓨
+ bool isStopTreading = false;
+#else
+ // WebSocket 瀹炵幇锛圵ebGL骞冲彴锛�
+ WebSocket webSocket;
+ public WebSocket socket { get { return webSocket; } }
+#endif
- public bool connected { get { return m_Socket == null ? false : m_Socket.Connected; } }
+ public Action OnDisconnected;
+
+ private long getBytesTotal = 0;
+ private long sendBytesTotal = 0;
+
+ public bool connected
+ {
+ get
+ {
+#if !UNITY_WEBGL && !H5_VERSION
+ return m_Socket == null ? false : m_Socket.Connected;
+#else
+ return webSocket != null && webSocket.State == WebSocketState.Open;
+#endif
+ }
+ }
ServerType socketType = ServerType.Main;
DateTime m_LastPackageTime;
public DateTime lastPackageTime { get { return m_LastPackageTime; } }
- bool isStopTreading = false;
-
string ip;
int port;
Action<bool> onConnected = null;
+ Queue<byte[]> sendQueue = new Queue<byte[]>();
+ static byte[] vCmdBytes = new byte[2];
public ClientSocket(ServerType type)
{
this.socketType = type;
}
+
+#if !UNITY_WEBGL && !H5_VERSION
+ // ==================== TCP Socket 瀹炵幇 ====================
public void Connect(string _ip, int _port, Action<bool> _onConnected)
{
@@ -260,7 +294,6 @@
}
- static byte[] vCmdBytes = new byte[2];
/// <summary>
/// 瑙f瀽鏁版嵁鍖咃細 FFCC+灏佸寘闀垮害+灏佸寘锛堝皝鍖呭ご+鏁版嵁锛夌粨鏋勪綋鍐呭
/// </summary>
@@ -346,71 +379,14 @@
}
- /// <summary>
- /// 鍙戦�佷俊鎭�
- /// </summary>
- public void SendInfo(GameNetPackBasic protocol)
- {
- if (!connected)
- {
- return;
- }
-
- if (protocol == null)
- {
- Debug.LogError("瑕佸彂鐨勪俊鎭璞′负绌�");
- return;
- }
-
- // if (Launch.Instance.EnableNetLog)
- // {
- // Debug.LogFormat("鍙戝寘锛歿0}", protocol.GetType().Name);
- // }
-
- if (protocol.combineBytes == null)
- {
- protocol.WriteToBytes();
- }
- protocol.CombineDatas(encoder);
-#if UNITY_EDITOR
- NetPkgCtl.RecordPackage(socketType, protocol.vInfoCont, NetPackagetType.Client, protocol.ToString(), FieldPrint.PrintFields(protocol), FieldPrint.PrintFieldsExpand(protocol, true));
-#endif
- sendBytesTotal += protocol.combineBytes.Length;
- SendBytes(protocol.combineBytes);
- }
-
- /// <summary>
- /// 鍙戦�佷俊鎭�
- /// </summary>
- /// <param name="vBytes"></param>
- public void SendInfo(byte[] vBytes)
- {
- if (!connected)
- {
- Debug.LogError("灏氭湭涓庤鍚庣閾炬帴锛佹棤娉曞彂閫佷俊鎭�");
- return;
- }
-
- if (vBytes == null || vBytes.Length < 2)
- {
- Debug.LogError("瑕佸彂鐨勪俊鎭暟鎹负绌烘垨鏁版嵁涓嶈冻");
- return;
- }
-
- vBytes = encoder.BaseXorAdd(vBytes);
- byte[] vFrameHead = new byte[] { 255, 204 };
- byte[] vMsgBodyLength = BitConverter.GetBytes(vBytes.Length);
- byte[] vTotal = new byte[vBytes.Length + 6];
- Array.Copy(vFrameHead, 0, vTotal, 0, vFrameHead.Length);
- Array.Copy(vMsgBodyLength, 0, vTotal, 2, vMsgBodyLength.Length);
- Array.Copy(vBytes, 0, vTotal, 6, vBytes.Length);
-
- SendBytes(vTotal);
- }
-
- Queue<byte[]> sendQueue = new Queue<byte[]>();
+ // TCP Socket 鐨� SendBytes锛堢鏈夋柟娉曪紝鐢辩粺涓�鐨� SendInfo 璋冪敤锛�
private void SendBytes(byte[] bytes)
{
+ // 璋冭瘯鏃ュ織锛氳緭鍑哄彂閫佺殑瀛楄妭鏁版嵁
+ // string hexString = "[TCP] SendBytes Length=" + bytes.Length + " Data=" + BitConverter.ToString(bytes, 0, Math.Min(bytes.Length, 32)).Replace("-", " ");
+ // if (bytes.Length > 32) hexString += "...";
+ // Debug.Log(hexString);
+
try
{
if (sendQueue.Count > 0)
@@ -448,4 +424,279 @@
}
}
+ public void DispatchMessageQueue()
+ {
+ // TCP涓嶉渶瑕佽疆璇�
+ }
+
+#else
+ // ==================== WebSocket 瀹炵幇锛圵ebGL骞冲彴锛�====================
+
+ public async void Connect(string _ip, int _port, Action<bool> _onConnected)
+ {
+ ip = _ip;
+ port = _port;
+ onConnected = _onConnected;
+
+ string url = $"ws://{_ip}:{_port}";
+ Debug.Log($"[ClientSocket-WebSocket] 寮�濮嬭繛鎺�: {url}");
+
+ try
+ {
+ webSocket = new WebSocket(url);
+
+ // 娉ㄥ唽WebSocket鍥炶皟
+ webSocket.OnOpen += OnWebSocketOpen;
+ webSocket.OnMessage += OnWebSocketMessage;
+ webSocket.OnError += OnWebSocketError;
+ webSocket.OnClose += OnWebSocketClose;
+
+ await webSocket.Connect();
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 杩炴帴寮傚父: {ex.Message}");
+ if (onConnected != null)
+ {
+ onConnected(false);
+ onConnected = null;
+ }
+ }
+ }
+
+ private void OnWebSocketOpen()
+ {
+ Debug.Log("[ClientSocket-WebSocket] 杩炴帴鎴愬姛");
+ m_LastPackageTime = DateTime.Now;
+
+ if (onConnected != null)
+ {
+ onConnected(true);
+ onConnected = null;
+ }
+ }
+
+ private void OnWebSocketMessage(byte[] data)
+ {
+ try
+ {
+ getBytesTotal += data.Length;
+
+ // WebSocket鏄秷鎭ā寮忥紝姣忔鏀跺埌瀹屾暣鍖咃紝鐩存帴澶勭悊
+ byte[] fixBytes = data;
+ int vReadIndex = 0;
+ byte[] vPackBytes;
+ int vLeavingLeng = 0;
+ int vBodyLeng = 0;
+ int vTotalLeng = fixBytes.Length;
+ GameNetPackBasic vNetpack;
+
+ while (vReadIndex < vTotalLeng)
+ {
+ vLeavingLeng = vTotalLeng - vReadIndex;
+ if (vLeavingLeng < 6)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 鍖呮暟鎹笉瓒�: {vLeavingLeng} bytes");
+ break;
+ }
+
+ vBodyLeng = BitConverter.ToInt32(fixBytes, vReadIndex + 2);
+ if (vBodyLeng > vLeavingLeng - 6)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 鍖呴暱搴︿笉鍖归厤: 澹版槑 {vBodyLeng + 6}, 瀹為檯 {vLeavingLeng}");
+ break;
+ }
+
+ vPackBytes = new byte[vBodyLeng];
+ Array.Copy(fixBytes, vReadIndex + 6, vPackBytes, 0, vBodyLeng);
+
+ vPackBytes = encoder.BaseXorSub(vPackBytes);
+ Array.Copy(vPackBytes, 0, vCmdBytes, 0, 2);
+ var cmd = (ushort)((ushort)(vCmdBytes[0] << 8) + vCmdBytes[1]);
+ bool isRegist = false;
+
+ if (PackageRegedit.Contain(cmd))
+ {
+ vNetpack = PackageRegedit.TransPack(socketType, cmd, vPackBytes);
+ if (vNetpack != null)
+ {
+ m_LastPackageTime = DateTime.Now;
+ GameNetSystem.Instance.PushPackage(vNetpack, socketType);
+ isRegist = true;
+ }
+ }
+
+ vReadIndex += 6 + vBodyLeng;
+
+ if (!isRegist)
+ {
+#if UNITY_EDITOR
+ PackageRegedit.TransPack(socketType, cmd, vPackBytes);
+#endif
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 鏀跺寘寮傚父锛歿ex}");
+ }
+ }
+
+ private void OnWebSocketError(string error)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 閿欒: {error}");
+ }
+
+ private void OnWebSocketClose(WebSocketCloseCode code)
+ {
+ Debug.Log($"[ClientSocket-WebSocket] 杩炴帴鍏抽棴: {code}");
+ OnDisconnected?.Invoke();
+ }
+
+ public async void CloseConnect()
+ {
+ Debug.Log("[ClientSocket-WebSocket] ==== CloseConnect");
+
+ if (webSocket != null)
+ {
+ sendQueue.Clear();
+ await webSocket.Close();
+ webSocket = null;
+ }
+ }
+
+ private bool isSending = false;
+
+ private async void SendBytes(byte[] bytes)
+ {
+ // 璋冭瘯鏃ュ織锛氳緭鍑哄彂閫佺殑瀛楄妭鏁版嵁
+ // string hexString = "[WebSocket] SendBytes Length=" + bytes.Length + " Data=" + BitConverter.ToString(bytes, 0, Math.Min(bytes.Length, 32)).Replace("-", " ");
+ // if (bytes.Length > 32) hexString += "...";
+ // Debug.Log(hexString);
+
+ if (webSocket == null || webSocket.State != WebSocketState.Open)
+ {
+ Debug.LogError("[ClientSocket-WebSocket] 鏈繛鎺ワ紝鏃犳硶鍙戦��");
+ return;
+ }
+
+ // 闃熷垪鏈哄埗
+ lock (sendQueue)
+ {
+ if (isSending)
+ {
+ sendQueue.Enqueue(bytes);
+ return;
+ }
+ isSending = true;
+ }
+
+ try
+ {
+ await webSocket.Send(bytes);
+
+ // 澶勭悊闃熷垪涓殑涓嬩竴涓�
+ lock (sendQueue)
+ {
+ if (sendQueue.Count > 0)
+ {
+ byte[] nextBytes = sendQueue.Dequeue();
+ isSending = false;
+ SendBytes(nextBytes); // 閫掑綊鍙戦��
+ }
+ else
+ {
+ isSending = false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError($"[ClientSocket-WebSocket] 鍙戦�佸紓甯�: {ex.Message}");
+ lock (sendQueue)
+ {
+ isSending = false;
+ }
+ }
+ }
+
+ // WebGL闇�瑕佸湪Update涓疆璇㈡秷鎭�
+ public void DispatchMessageQueue()
+ {
+// #if !UNITY_EDITOR
+ webSocket?.DispatchMessageQueue();
+// #endif
+ }
+
+#endif
+
+ // ==================== 缁熶竴鐨勫叕鍏辨帴鍙o紙涓や釜骞冲彴閫氱敤锛�====================
+
+ /// <summary>
+ /// 鍙戦�佸崗璁寘
+ /// </summary>
+ public void SendInfo(GameNetPackBasic protocol)
+ {
+ if (!connected)
+ {
+ return;
+ }
+
+ if (protocol == null)
+ {
+ Debug.LogError("瑕佸彂鐨勪俊鎭璞′负绌�");
+ return;
+ }
+
+ if (protocol.combineBytes == null)
+ {
+ protocol.WriteToBytes();
+ }
+ protocol.CombineDatas(encoder);
+
+#if UNITY_EDITOR
+ NetPkgCtl.RecordPackage(socketType, protocol.vInfoCont, NetPackagetType.Client,
+ protocol.ToString(), FieldPrint.PrintFields(protocol), FieldPrint.PrintFieldsExpand(protocol, true));
+#endif
+
+ // 璋冭瘯鏃ュ織锛氭煡鐪� combineBytes 鐨勫唴瀹�
+ string hexString = "[SendInfo] Protocol=" + protocol.ToString() + " combineBytes.Length=" + protocol.combineBytes.Length +
+ " Data=" + BitConverter.ToString(protocol.combineBytes, 0, Math.Min(protocol.combineBytes.Length, 32)).Replace("-", " ");
+ if (protocol.combineBytes.Length > 32) hexString += "...";
+ Debug.Log(hexString);
+
+ sendBytesTotal += protocol.combineBytes.Length;
+ SendBytes(protocol.combineBytes);
+ }
+
+#if UNITY_EDITOR
+ /// <summary>
+ /// 鍙戦�佸師濮嬪瓧鑺傛暟鎹�
+ /// </summary>
+ public void SendInfo(byte[] vBytes)
+ {
+ if (!connected)
+ {
+ Debug.LogError("灏氭湭涓庤鍚庣閾炬帴锛佹棤娉曞彂閫佷俊鎭�");
+ return;
+ }
+
+ if (vBytes == null || vBytes.Length < 2)
+ {
+ Debug.LogError("瑕佸彂鐨勪俊鎭暟鎹负绌烘垨鏁版嵁涓嶈冻");
+ return;
+ }
+
+ // 鍔犲瘑骞剁粍瑁呭寘澶�
+ vBytes = encoder.BaseXorAdd(vBytes);
+ byte[] vFrameHead = new byte[] { 255, 204 };
+ byte[] vMsgBodyLength = BitConverter.GetBytes(vBytes.Length);
+ byte[] vTotal = new byte[vBytes.Length + 6];
+ Array.Copy(vFrameHead, 0, vTotal, 0, vFrameHead.Length);
+ Array.Copy(vMsgBodyLength, 0, vTotal, 2, vMsgBodyLength.Length);
+ Array.Copy(vBytes, 0, vTotal, 6, vBytes.Length);
+
+ SendBytes(vTotal);
+ }
+#endif
}
--
Gitblit v1.8.0