#if UNITY_WEBGL // && !UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using AOT;
namespace XGame.Framework.Network.Web
{
///
/// Class providing static access methods to work with JSLIB WebSocket
///
internal static class WebSocketService
{
/* Map of websocket instances */
private static Dictionary sockets = new Dictionary();
/* Delegates */
public delegate void OnOpenCallback(int instanceId);
public delegate void OnMessageCallback(int instanceId, IntPtr msgPtr, int msgSize);
public delegate void OnMessageStrCallback(int instanceId, IntPtr msgStrPtr);
public delegate void OnErrorCallback(int instanceId, IntPtr errorPtr);
public delegate void OnCloseCallback(int instanceId, int closeCode, IntPtr reasonPtr);
/* WebSocket JSLIB functions */
[DllImport("__Internal")]
public static extern int WebSocketConnect(int instanceId);
[DllImport("__Internal")]
public static extern int WebSocketClose(int instanceId, int code, string reason);
[DllImport("__Internal")]
public static extern int WebSocketSend(int instanceId, byte[] dataPtr, int dataLength);
[DllImport("__Internal")]
public static extern int WebSocketSendStr(int instanceId, string data);
[DllImport("__Internal")]
public static extern int WebSocketGetState(int instanceId);
/* WebSocket JSLIB callback setters and other functions */
[DllImport("__Internal")]
public static extern int WebSocketAllocate(string url);
[DllImport("__Internal")]
public static extern int WebSocketAddSubProtocol(int instanceId, string protocol);
[DllImport("__Internal")]
public static extern void WebSocketFree(int instanceId);
[DllImport("__Internal")]
public static extern void WebSocketSetOnOpen(OnOpenCallback callback);
[DllImport("__Internal")]
public static extern void WebSocketSetOnMessage(OnMessageCallback callback);
[DllImport("__Internal")]
public static extern void WebSocketSetOnMessageStr(OnMessageStrCallback callback);
[DllImport("__Internal")]
public static extern void WebSocketSetOnError(OnErrorCallback callback);
[DllImport("__Internal")]
public static extern void WebSocketSetOnClose(OnCloseCallback callback);
/* If callbacks was initialized and set */
private static bool isInitialized = false;
/* Initialize WebSocket callbacks to JSLIB */
private static void Initialize()
{
WebSocketSetOnOpen(DelegateOnOpenEvent);
WebSocketSetOnMessage(DelegateOnMessageEvent);
WebSocketSetOnMessageStr(DelegateOnMessageStrEvent);
WebSocketSetOnError(DelegateOnErrorEvent);
WebSocketSetOnClose(DelegateOnCloseEvent);
isInitialized = true;
}
[MonoPInvokeCallback(typeof(OnOpenCallback))]
public static void DelegateOnOpenEvent(int instanceId)
{
if (sockets.TryGetValue(instanceId, out var socket))
{
socket.HandleOnOpen();
}
}
[MonoPInvokeCallback(typeof(OnMessageCallback))]
public static void DelegateOnMessageEvent(int instanceId, IntPtr msgPtr, int msgSize)
{
if (sockets.TryGetValue(instanceId, out var socket))
{
var bytes = SessionBufferPool.Acquire();
Marshal.Copy(msgPtr, bytes, 0, msgSize);
socket.HandleOnMessage(bytes, 0, msgSize);
}
}
[MonoPInvokeCallback(typeof(OnMessageStrCallback))]
public static void DelegateOnMessageStrEvent(int instanceId, IntPtr msgStrPtr)
{
if (sockets.TryGetValue(instanceId, out var socket))
{
string msgStr = Marshal.PtrToStringAuto(msgStrPtr);
socket.HandleOnMessageStr(msgStr);
}
}
[MonoPInvokeCallback(typeof(OnErrorCallback))]
public static void DelegateOnErrorEvent(int instanceId, IntPtr errorPtr)
{
if (sockets.TryGetValue(instanceId, out var socket))
{
string errorMsg = Marshal.PtrToStringAuto(errorPtr);
socket.HandleOnError(errorMsg);
}
}
[MonoPInvokeCallback(typeof(OnCloseCallback))]
public static void DelegateOnCloseEvent(int instanceId, int closeCode, IntPtr reasonPtr)
{
if (sockets.TryGetValue(instanceId, out var socket))
{
string reason = Marshal.PtrToStringAuto(reasonPtr);
socket.HandleOnClose((ushort)closeCode, reason);
sockets.Remove(instanceId);
}
}
internal static int AllocateInstance(string address)
{
if (!isInitialized) Initialize();
return WebSocketAllocate(address);
}
internal static void Add(WebSocket socket)
{
if (!sockets.ContainsKey(socket.instanceId))
{
sockets.Add(socket.instanceId, socket);
}
}
internal static void Remove(int instanceId)
{
if (sockets.ContainsKey(instanceId))
{
sockets.Remove(instanceId);
}
}
}
}
#endif