Web socket and WebAssembly

Hello, I want to know if it is possible to make a game with WebAssembly and WebSocket, and the integration technologies , eg: js and node.js

You can use Simple Web Sockets for Unity WebGL | Tutorial Projects | Unity Asset Store in unity side, it work in WebGL too (by JS plugin built-in) (also in PC and editor by other DLL)

Write your WS-Server as you like, in node.js or java etc

Thats the message in the AssetStore…
Unfortunately, Simple Web Sockets for Unity WebGL is no longer available.
This package has been deprecated from the Asset Store.

So whats the options now? I tryed to use websocket-sharp but with no success in WebGl builds.

I’m NOT the autor, and will NOT support this.
Included as is.

It work in our project, in webgl too.

websocket-sharp.dll can be downloaded separately - it only need for PC \ Editor.
In webgl - it uses jslib (can place to Plugins folder, or not)

NetManager.cs

using System;
using System.Collections;
using UnityEngine;

public class NetManager : MonoBehaviour {

    private WebSocket _webSocket;


    public IEnumerator openSocket(string serverIp, string port)
    {
        //string url = "ws://" + serverIp + ":" + port + "/websocket";
        string url = "wss://echo.websocket.org/"; // todo
        Debug.Log("Opening connection to " + url);
        Controller.instance.toLog("NetManager Opening connection to " + url);
        _webSocket = new WebSocket(new Uri(url));
        yield return StartCoroutine(_webSocket.Connect());
        Debug.Log("Connected");
        Controller.instance.toLog("connected");
        StartCoroutine(readSocketCoroutine());
    }

    private IEnumerator readSocketCoroutine()
    {
        while (true)
        {
            if (_webSocket.error != null)
            {
                Debug.LogError("NetManager Error: " + _webSocket.error);
                Controller.instance.toLog("NetManager Error: " + _webSocket.error);
                break;
            }

            const int maxProcessibleMessagesPerFrame = 100;
            for (int i = 0; i < maxProcessibleMessagesPerFrame; i++)
            {
                string message = _webSocket.RecvString();
                if (message == null) break;
                onMsgReceived(message);
            }
       
            yield return 0;
        }
        _webSocket.Close();
    }

    private void onMsgReceived(string msg)
    {
        Debug.Log("Received: " + msg);
        Controller.instance.onMessageReceived(msg);
    }

    public void SendStringOnServer(string message)
    {
        Debug.Log("SendStringOnServer: " + message);
        _webSocket.SendString(message);
    }
}

WebSocket.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using UnityEngine;
using System.Runtime.InteropServices;

public class WebSocket
{
    private Uri mUrl;

    public WebSocket(Uri url)
    {
        mUrl = url;

        string protocol = mUrl.Scheme;
        if (!protocol.Equals("ws") && !protocol.Equals("wss"))
            throw new ArgumentException("Unsupported protocol: " + protocol);
    }

    public void SendString(string str)
    {
        Send(Encoding.UTF8.GetBytes (str));
    }

    public string RecvString()
    {
        byte[] retval = Recv();
        if (retval == null)
            return null;
        return Encoding.UTF8.GetString (retval);
    }

#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern int SocketCreate (string url);

    [DllImport("__Internal")]
    private static extern int SocketState (int socketInstance);

    [DllImport("__Internal")]
    private static extern void SocketSend (int socketInstance, byte[] ptr, int length);

    [DllImport("__Internal")]
    private static extern void SocketRecv (int socketInstance, byte[] ptr, int length);

    [DllImport("__Internal")]
    private static extern int SocketRecvLength (int socketInstance);

    [DllImport("__Internal")]
    private static extern void SocketClose (int socketInstance);

    [DllImport("__Internal")]
    private static extern int SocketError (int socketInstance, byte[] ptr, int length);

    int m_NativeRef = 0;

    public void Send(byte[] buffer)
    {
        SocketSend (m_NativeRef, buffer, buffer.Length);
    }

    public byte[] Recv()
    {
        int length = SocketRecvLength (m_NativeRef);
        if (length == 0)
            return null;
        byte[] buffer = new byte[length];
        SocketRecv (m_NativeRef, buffer, length);
        return buffer;
    }

    public IEnumerator Connect()
    {
        m_NativeRef = SocketCreate (mUrl.ToString());

        while (SocketState(m_NativeRef) == 0)
            yield return 0;
    }
    public void Close()
    {
        SocketClose(m_NativeRef);
    }

    const int ErrorBufferSize = 1024;
    private byte[] _errorBuffer = new byte[ErrorBufferSize];
    //
    public string error
    {
        get {
            int result = SocketError (m_NativeRef, _errorBuffer, ErrorBufferSize);
            if (result == 0) return null;
            return Encoding.UTF8.GetString(_errorBuffer);           
        }
    }
#else
    WebSocketSharp.WebSocket m_Socket;
    Queue<byte[]> m_Messages = new Queue<byte[]>();
    bool m_IsConnected = false;
    string m_Error = null;

    public IEnumerator Connect()
    {
        m_Socket = new WebSocketSharp.WebSocket(mUrl.ToString());

        m_Socket.OnMessage +=
            (sender, e) =>
            {
                lock (m_Messages)
                {
                    m_Messages.Enqueue(e.RawData);
                }
            };

        m_Socket.OnOpen += (sender, e) => m_IsConnected = true;
        m_Socket.OnError += (sender, e) => m_Error = e.Message;
        m_Socket.ConnectAsync();

        while (!m_IsConnected && m_Error == null)
            yield return 0;
    }

    public void Send(byte[] buffer)
    {
        m_Socket.Send(buffer);
    }

    public byte[] Recv()
    {
        lock (m_Messages)
        {
            if (m_Messages.Count == 0) return null;
            return m_Messages.Dequeue();
        }
    }

    public void Close()
    {
        m_Socket.Close();
    }

    public string error
    {
        get {
            return m_Error;
        }
    }
#endif
}

WebSocket.jslib

var LibraryWebSockets = {
$webSocketInstances: [],

SocketCreate: function(url)
{
    var str = Pointer_stringify(url);
    var socket = {
        socket: new WebSocket(str),
        buffer: new Uint8Array(0),
        error: null,
        messages: []
    }

    socket.socket.binaryType = 'arraybuffer';

    socket.socket.onmessage = function (e) {
        // Todo: handle other data types?
        if (e.data instanceof Blob)
        {
            var reader = new FileReader();
            reader.addEventListener("loadend", function() {
                var array = new Uint8Array(reader.result);
                socket.messages.push(array);
            });
            reader.readAsArrayBuffer(e.data);
        }
        else if (e.data instanceof ArrayBuffer)
        {
            var array = new Uint8Array(e.data);
            socket.messages.push(array);
        }
    };

    socket.socket.onclose = function (e) {
        if (e.code != 1000)
        {
            if (e.reason != null && e.reason.length > 0)
                socket.error = e.reason;
            else
            {
                switch (e.code)
                {
                    case 1001:
                        socket.error = "Endpoint going away.";
                        break;
                    case 1002:
                        socket.error = "Protocol error.";
                        break;
                    case 1003:
                        socket.error = "Unsupported message.";
                        break;
                    case 1005:
                        socket.error = "No status.";
                        break;
                    case 1006:
                        socket.error = "Abnormal disconnection.";
                        break;
                    case 1009:
                        socket.error = "Data frame too large.";
                        break;
                    default:
                        socket.error = "Error "+e.code;
                }
            }
        }
    }
    var instance = webSocketInstances.push(socket) - 1;
    return instance;
},

SocketState: function (socketInstance)
{
    var socket = webSocketInstances[socketInstance];
    return socket.socket.readyState;
},

SocketError: function (socketInstance, ptr, bufsize)
{
     var socket = webSocketInstances[socketInstance];
     if (socket.error == null)
         return 0;
    var str = socket.error.slice(0, Math.max(0, bufsize - 1));
    writeStringToMemory(str, ptr, false);
    return 1;
},

SocketSend: function (socketInstance, ptr, length)
{
    var socket = webSocketInstances[socketInstance];
    socket.socket.send (HEAPU8.buffer.slice(ptr, ptr+length));
},

SocketRecvLength: function(socketInstance)
{
    var socket = webSocketInstances[socketInstance];
    if (socket.messages.length == 0)
        return 0;
    return socket.messages[0].length;
},

SocketRecv: function (socketInstance, ptr, length)
{
    var socket = webSocketInstances[socketInstance];
    if (socket.messages.length == 0)
        return 0;
    if (socket.messages[0].length > length)
        return 0;
    HEAPU8.set(socket.messages[0], ptr);
    socket.messages = socket.messages.slice(1);
},

SocketClose: function (socketInstance)
{
    var socket = webSocketInstances[socketInstance];
    socket.socket.close();
}
};

autoAddDeps(LibraryWebSockets, '$webSocketInstances');
mergeInto(LibraryManager.library, LibraryWebSockets);

license from original
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.