114 lines
3.6 KiB
C#
114 lines
3.6 KiB
C#
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;
|
|
}
|
|
}
|
|
} |