Comments (1)
#if UNITY_WEBGL
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using AOT;
using Google.Protobuf;
using WebSocketSharp;
namespace Nakama
{
public class NTransportJavascript : INTransport
{
private static INLogger _logger;
public INLogger Logger
{
get { return _logger; }
set { _logger = value; }
}
private static bool _trace;
public bool Trace {
get { return _trace; }
set { _trace = value; }
}
private static readonly IDictionary<int, string> CloseErrorMessages = new Dictionary<int, string> {
{ 1000, "Normal" },
{ 1001, "Away" },
{ 1002, "ProtocolError" },
{ 1003, "UnsupportedData" },
{ 1004, "Undefined" },
{ 1005, "NoStatus" },
{ 1006, "Abnormal" },
{ 1007, "InvalidData" },
{ 1008, "PolicyViolation" },
{ 1009, "TooBig" },
{ 1010, "MandatoryExtension" },
{ 1011, "ServerError" },
{ 1015, "TlsHandshakeFailure" }
};
private static readonly IDictionary<string, KeyValuePair<Action<byte[]>, Action<Exception>>> AuthHandlers = new Dictionary<string, KeyValuePair<Action<byte[]>, Action<Exception>>>();
private static readonly IDictionary<string, EventHandler<WebSocketCloseEventArgs>> SocketCloseHandlers = new Dictionary<string, EventHandler<WebSocketCloseEventArgs>>();
private static readonly IDictionary<string, EventHandler<WebSocketErrorEventArgs>> SocketErrorHandlers = new Dictionary<string, EventHandler<WebSocketErrorEventArgs>>();
private static readonly IDictionary<string, EventHandler<WebSocketMessageEventArgs>> SocketMessageHandlers = new Dictionary<string, EventHandler<WebSocketMessageEventArgs>>();
private static readonly IDictionary<string, EventHandler> SocketOpenHandlers = new Dictionary<string, EventHandler>();
private static readonly IDictionary<string, Action> SocketCloseCallbacks = new Dictionary<string, Action>();
private static readonly IDictionary<string, Action<bool>> SocketOpenCallbacks = new Dictionary<string, Action<bool>>();
private readonly string _socketId = Guid.NewGuid().ToString();
public event EventHandler<WebSocketCloseEventArgs> OnClose {
add { SocketCloseHandlers.Add(_socketId, value); }
remove { SocketCloseHandlers.Remove(_socketId); }
}
public event EventHandler<WebSocketErrorEventArgs> OnError {
add { SocketErrorHandlers.Add(_socketId, value); }
remove { SocketErrorHandlers.Remove(_socketId); }
}
public event EventHandler<WebSocketMessageEventArgs> OnMessage {
add { SocketMessageHandlers.Add(_socketId, value); }
remove { SocketMessageHandlers.Remove(_socketId); }
}
public event EventHandler OnOpen {
add { SocketOpenHandlers.Add(_socketId, value); }
remove { SocketOpenHandlers.Remove(_socketId); }
}
private int _socketNativeRef = -1;
public NTransportJavascript()
{
InitTransport(AuthSuccessCallback, AuthErrorCallback, OnSocketOpen, OnSocketError, OnSocketMessage, OnSocketClose);
}
[DllImport("__Internal")]
public static extern void InitTransport(Action<string, string> successCallback,
Action<string> failureCallback,
Action<string> socketOpen,
Action<string> socketError,
Action<string, string> socketMessage,
Action<string, string> socketClose
);
[DllImport("__Internal")]
private static extern int FetchPost(string handlerId, string uri, string payload, string authHeader, string langHeader);
[MonoPInvokeCallback(typeof(Action<string, string>))]
public static void AuthSuccessCallback(string handlerId, string data)
{
_logger.TraceFormatIf(_trace, "WebGL auth-success callback");
var kv = AuthHandlers[handlerId];
AuthHandlers.Remove(handlerId);
kv.Key(Convert.FromBase64String(data));
}
[MonoPInvokeCallback(typeof(Action<string>))]
public static void AuthErrorCallback(string handlerId)
{
_logger.TraceFormatIf(_trace, "WebGL auth-error callback");
var kv = AuthHandlers[handlerId];
AuthHandlers.Remove(handlerId);
kv.Value(new Exception("Network request failed."));
}
public void Post(string uri, AuthenticateRequest payload, string authHeader, string langHeader, uint timeout,
uint connectTimeout, Action<byte[]> successAction, Action<Exception> errorAction)
{
var handlerId = Guid.NewGuid().ToString();
AuthHandlers.Add(handlerId, new KeyValuePair<Action<byte[]>, Action<Exception>>(successAction, errorAction));
var base64Payload = Convert.ToBase64String(payload.ToByteArray());
FetchPost(handlerId, uri, base64Payload, authHeader, langHeader);
}
// ----
[DllImport("__Internal")]
private static extern int CreateSocket(string socketId, string uri);
[DllImport("__Internal")]
private static extern void CloseSocket(int socketRef);
[DllImport("__Internal")]
private static extern void SendData(int socketRef, string data);
[DllImport("__Internal")]
private static extern int SocketState(int socketRef);
[MonoPInvokeCallback(typeof(Action<string>))]
public static void OnSocketOpen(string socketId)
{
_logger.TraceFormatIf(_trace, "WebGL onsocketopen callback - socket: {0}", socketId);
if (SocketOpenHandlers.ContainsKey(socketId))
{
SocketOpenHandlers[socketId].Emit(null, EventArgs.Empty);
}
if (SocketOpenCallbacks.ContainsKey(socketId))
{
SocketOpenCallbacks[socketId](true);
}
}
[MonoPInvokeCallback(typeof(Action<string>))]
public static void OnSocketError(string socketId)
{
_logger.TraceFormatIf(_trace, "WebGL onsocketerror callback - socket: {0}", socketId);
if (SocketErrorHandlers.ContainsKey(socketId))
{
SocketErrorHandlers[socketId].Emit(null, new WebSocketErrorEventArgs(new Exception("WebSocket error occured")));
}
}
[MonoPInvokeCallback(typeof(Action<string, string>))]
public static void OnSocketMessage(string socketId, string data)
{
_logger.TraceFormatIf(_trace, "WebGL onsocketmessage callback - socket: {0}", socketId);
if (SocketMessageHandlers.ContainsKey(socketId))
{
var dataBytes = Convert.FromBase64String(data);
SocketMessageHandlers[socketId].Emit(null, new WebSocketMessageEventArgs(dataBytes));
}
}
[MonoPInvokeCallback(typeof(Action<string, string>))]
public static void OnSocketClose(string socketId, string closeStatus)
{
_logger.TraceFormatIf(_trace, "WebGL onsocketclose callback - socket {0} - status: {1}", socketId, closeStatus);
var closeStatusCode = Convert.ToInt32(closeStatus);
if (SocketCloseHandlers.ContainsKey(socketId))
{
SocketCloseHandlers[socketId].Emit(null, new WebSocketCloseEventArgs(closeStatusCode, CloseErrorMessages[closeStatusCode]));
}
if (SocketCloseCallbacks.ContainsKey(socketId))
{
SocketCloseCallbacks[socketId]();
}
SocketCloseHandlers.Remove(socketId);
SocketCloseCallbacks.Remove(socketId);
}
public void Connect(string uri)
{
// This is not a blocking call
// connection happen on socket creation
if (_socketNativeRef == -1)
{
_socketNativeRef = CreateSocket(_socketId, uri);
}
}
public void ConnectAsync(string uri, Action<bool> callback)
{
// connection happen on socket creation
if (_socketNativeRef == -1)
{
SocketOpenCallbacks.Add(_socketId, callback);
_socketNativeRef = CreateSocket(_socketId, uri);
}
}
public void Close()
{
CloseSocket(_socketNativeRef);
}
public void CloseAsync(Action callback)
{
SocketCloseCallbacks.Add(_socketId, callback);
CloseSocket(_socketNativeRef);
}
public void Send(byte[] data)
{
var base64Payload = Convert.ToBase64String(data);
SendData(_socketNativeRef, base64Payload);
}
public void SendAsync(byte[] data, Action<bool> callback)
{
var base64Payload = Convert.ToBase64String(data);
SendData(_socketNativeRef, base64Payload);
callback(true);
}
}
}
#endif
Its just two lines
#if UNITY_WEBGL
at the first line and
#endif
at the bottom
from nakama-unity.
Related Issues (20)
- Unity - Investigate whether copying of package for asset store release process generates new GUIDs HOT 1
- Unity - [WebGL] SOCKET_REF_MAP.has is not a function HOT 2
- IOS 15 Crash HOT 1
- Could you please provide original C# code for nakama.DLL? HOT 12
- `HttpRequestAdapter` and `WebSocketAdapter` don't connect properly over local network on iOS
- Dont get data of leaderboard HOT 9
- Illegal Byte Sequence during auth when path has chinese characters in it (mono issue) HOT 1
- UnityWebRequestAdapter doesn't write logs to ILogger HOT 1
- Storage write rejected - version check failed HOT 5
- SocketException: mono-io-layer-error (61) on iOS device for AuthenticateDeviceAsync HOT 1
- Imatch Presences is empty HOT 1
- Connect to database HOT 2
- Use database and redis HOT 2
- The document on the official website has not been updated HOT 3
- C# / Unity - [BUG] Client does not get return from server API call HOT 2
- [Ehancement] Open-Source Nakama.dll - Plugins HOT 1
- Doesn't support leaderboard rank counts yet HOT 1
- Trouble with Socket.AddMatchmakerAsync in Nakama HOT 1
- IEnumerable<IApiStorageObject>' does not contain a definition for 'Any' and no accessible extension method 'Any' accepting a first argument of type 'IEnumerable<IApiStorageObject>' could be found (are you missing a using directive or an assembly reference?) HOT 1
- MacOS support ? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nakama-unity.