using Godot; using Godot.Collections; public partial class EventDrivenWebSocket : WebSocketPeer { public delegate void WebSocketEventHandler(string eventName, params object[] args); public delegate void WSBinMsgEventHandler(byte[] args); public delegate void WSMsgEventHandler(string args); public event WebSocketEventHandler OnOpen; public event WSBinMsgEventHandler OnMessage; public event WSMsgEventHandler OnText; public event WSBinMsgEventHandler OnBinary; public event WebSocketEventHandler OnClose; public event WebSocketEventHandler OnError; private bool isConnected = false; private bool isCloseEventFired = false; private double connectingTime = double.NegativeInfinity; public EventDrivenWebSocket() : base() { isConnected = false; } public bool GetIsConnected() { return isConnected; } public void PollEx(double delta) { base.Poll(); CheckAndDispatchEvents(delta); } public void ConnectToUrlEx(string url, double delayTime = 3, TlsOptions tlsClientOptions = null) { if (connectingTime >= 0) { return; } Error err = ConnectToUrl(url, tlsClientOptions); if (err != Error.Ok) { OnError?.Invoke("error", err); } connectingTime = delayTime; } protected void CheckAndDispatchEvents(double delta) { var state = GetReadyState(); switch (state) { case State.Open when !isConnected: isConnected = true; OnOpen?.Invoke("open", null); break; case State.Open: while (GetAvailablePacketCount() > 0) { byte[] packet = GetPacket(); OnMessage?.Invoke(packet); if (WasStringPacket()) { OnText?.Invoke(packet.GetStringFromUtf8()); } else { OnBinary?.Invoke(packet); } } break; case State.Closed: connectingTime = double.NegativeInfinity; OnClose?.Invoke("closed", GetCloseCode(), GetCloseReason()); isConnected = false; break; case State.Closing: // OnClose?.Invoke("closing"); break; case State.Connecting: if (connectingTime >= 0) { connectingTime -= delta; } else if (connectingTime != double.NegativeInfinity){ connectingTime = double.NegativeInfinity; Close(); OnError?.Invoke("connectTimeOut", Error.Timeout); } break; default: // 可以在这里处理其他状态或错误 OnError?.Invoke("error", "Unknown WebSocket state."); break; } } public void SendBinaryEx(byte[] data) { SendEx(data); } public void SendJsonEx(Dictionary msg) { SendTextEx(Json.Stringify(msg)); } public Error SendTextEx(string message) { if (isConnected) { return SendText(message); } else { OnError?.Invoke("error", "Attempt to send on a closed connection."); return Error.ConnectionError; } } public Error SendEx(byte[] message, WriteMode writeMode = WriteMode.Binary) { if (isConnected) { return Send(message, writeMode); } else { OnError?.Invoke("error", "Attempt to send on a closed connection."); return Error.ConnectionError; } } }