_xiaofang/xiaofang/Assets/UnityWebSocket/Scripts/Runtime/Implementation/WebGL/WebSocket.cs
2024-11-23 14:08:04 +08:00

148 lines
5.2 KiB
C#

#if !UNITY_EDITOR && UNITY_WEBGL
using System;
namespace UnityWebSocket
{
public class WebSocket : IWebSocket
{
public string Address { get; private set; }
public string[] SubProtocols { get; private set; }
public WebSocketState ReadyState { get { return (WebSocketState)WebSocketManager.WebSocketGetState(instanceId); } }
public event EventHandler<OpenEventArgs> OnOpen;
public event EventHandler<CloseEventArgs> OnClose;
public event EventHandler<ErrorEventArgs> OnError;
public event EventHandler<MessageEventArgs> OnMessage;
internal int instanceId = 0;
public WebSocket(string address)
{
this.Address = address;
AllocateInstance();
}
public WebSocket(string address, string subProtocol)
{
this.Address = address;
this.SubProtocols = new string[] { subProtocol };
AllocateInstance();
}
public WebSocket(string address, string[] subProtocols)
{
this.Address = address;
this.SubProtocols = subProtocols;
AllocateInstance();
}
internal void AllocateInstance()
{
instanceId = WebSocketManager.AllocateInstance(this.Address);
Log($"Allocate socket with instanceId: {instanceId}");
if (this.SubProtocols == null) return;
foreach (var protocol in this.SubProtocols)
{
if (string.IsNullOrEmpty(protocol)) continue;
Log($"Add Sub Protocol {protocol}, with instanceId: {instanceId}");
int code = WebSocketManager.WebSocketAddSubProtocol(instanceId, protocol);
if (code < 0)
{
HandleOnError(GetErrorMessageFromCode(code));
break;
}
}
}
~WebSocket()
{
Log($"Free socket with instanceId: {instanceId}");
WebSocketManager.WebSocketFree(instanceId);
}
public void ConnectAsync()
{
Log($"Connect with instanceId: {instanceId}");
WebSocketManager.Add(this);
int code = WebSocketManager.WebSocketConnect(instanceId);
if (code < 0) HandleOnError(GetErrorMessageFromCode(code));
}
public void CloseAsync()
{
Log($"Close with instanceId: {instanceId}");
int code = WebSocketManager.WebSocketClose(instanceId, (int)CloseStatusCode.Normal, "Normal Closure");
if (code < 0) HandleOnError(GetErrorMessageFromCode(code));
}
public void SendAsync(string text)
{
Log($"Send, type: {Opcode.Text}, size: {text.Length}");
int code = WebSocketManager.WebSocketSendStr(instanceId, text);
if (code < 0) HandleOnError(GetErrorMessageFromCode(code));
}
public void SendAsync(byte[] data)
{
Log($"Send, type: {Opcode.Binary}, size: {data.Length}");
int code = WebSocketManager.WebSocketSend(instanceId, data, data.Length);
if (code < 0) HandleOnError(GetErrorMessageFromCode(code));
}
internal void HandleOnOpen()
{
Log("OnOpen");
OnOpen?.Invoke(this, new OpenEventArgs());
}
internal void HandleOnMessage(byte[] rawData)
{
Log($"OnMessage, type: {Opcode.Binary}, size: {rawData.Length}");
OnMessage?.Invoke(this, new MessageEventArgs(Opcode.Binary, rawData));
}
internal void HandleOnMessageStr(string data)
{
Log($"OnMessage, type: {Opcode.Text}, size: {data.Length}");
OnMessage?.Invoke(this, new MessageEventArgs(Opcode.Text, data));
}
internal void HandleOnClose(ushort code, string reason)
{
Log($"OnClose, code: {code}, reason: {reason}");
OnClose?.Invoke(this, new CloseEventArgs(code, reason));
WebSocketManager.Remove(instanceId);
}
internal void HandleOnError(string msg)
{
Log("OnError, error: " + msg);
OnError?.Invoke(this, new ErrorEventArgs(msg));
}
internal static string GetErrorMessageFromCode(int errorCode)
{
switch (errorCode)
{
case -1: return "WebSocket instance not found.";
case -2: return "WebSocket is already connected or in connecting state.";
case -3: return "WebSocket is not connected.";
case -4: return "WebSocket is already closing.";
case -5: return "WebSocket is already closed.";
case -6: return "WebSocket is not in open state.";
case -7: return "Cannot close WebSocket, An invalid code was specified or reason is too long.";
case -8: return "Not support buffer slice. ";
default: return $"Unknown error code {errorCode}.";
}
}
[System.Diagnostics.Conditional("UNITY_WEB_SOCKET_LOG")]
static void Log(string msg)
{
var time = DateTime.Now.ToString("HH:mm:ss.fff");
UnityEngine.Debug.Log($"[{time}][UnityWebSocket] {msg}");
}
}
}
#endif