1
\$\begingroup\$

Is there any way to implement websocket server, which I can run inside Unity3d standalone linux instance? I gonna connect to it directly from webpage (pure javascript, not Unity3d WebGL). I've tried to look for existing websockets libraries for C#, but the reason they does not fit because Unity3d can execute only Mono libraries with .NET 3.5 (.NET 4.6 in newest Unity3d 2017.1 release).

I have HttpListener server running fine, however for Websockets it needs lots of specific logic. Who knows any solution for this?

\$\endgroup\$
3
\$\begingroup\$

Websocket sharp: https://github.com/sta/websocket-sharp

It has a unity version which I've used as part of a cross-platform library and on a couple of local multiplayer games, and worked well. I have not tried using the server part of it though - only the client.

That said are you sure you want to have a unity app be the server? It might be more trouble than it's worth to make it discoverable on anything but a local network.

\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer. Actually I've used the same library to implement my own Websockets server inside Unity3d. Just required some magic, but it works awesome. \$\endgroup\$ – Epsiloncool Feb 20 '18 at 22:08
  • \$\begingroup\$ @Epsiloncool hi when I try running a simple demo on the webGL build I get the error exception thrown: RuntimeError: memory access out of bounds,RuntimeError: memory access out of bounds in the JavaScript console and it won't even start? Has this happened to you ever? I'm using unity 2018.3.2 \$\endgroup\$ – bluejayke Jan 24 at 6:34
  • \$\begingroup\$ @bluejayke Nah, sorry, I didn't try this with 2018.3.2. My version was 2017.1. \$\endgroup\$ – Epsiloncool Jan 24 at 12:14
  • \$\begingroup\$ BTW I just found github.com/jirihybek/unity-websocket-webgl and it works perfect with the newest version of unity, even the free version in the webGL player, for you and anyone else out there wondering :) \$\endgroup\$ – bluejayke Jan 24 at 22:31
  • \$\begingroup\$ With this repo, I'm getting errors with .NET 3.5 \$\endgroup\$ – Derk Jan Speelman Aug 16 at 13:49
4
\$\begingroup\$

System.Net.WebSockets seems to be completely built-in to .Net and freely available in Unity.

Here's a full Websockets client for Unity for example:

using System;
using System.Text;
using System.Threading;
using System.Net.WebSockets;
using UnityEngine;

public class Comms: MonoBehaviour {
    Uri u = new Uri("ws://blah blah.us-west-1.compute.amazonaws.com:3333");
    ClientWebSocket cws = null;
    ArraySegment<byte> buf = new ArraySegment<byte>(new byte[1024]);

    void Start() { Connect(); }

    async void Connect() {
        cws = new ClientWebSocket();
        try {
            await cws.ConnectAsync(u, CancellationToken.None);
            if (cws.State == WebSocketState.Open) Debug.Log("connected");
            SayHello();
            GetStuff();
        }
        catch (Exception e) { Debug.Log("woe " + e.Message); }
    }

    async void SayHello() {
        ArraySegment<byte> b = new ArraySegment<byte>(Encoding.UTF8.GetBytes("hello"));
        await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None);
    }

    async void GetStuff() {
        WebSocketReceiveResult r = await cws.ReceiveAsync(buf, CancellationToken.None);
        Debug.Log("Got: " + Encoding.UTF8.GetString(buf.Array, 0, r.Count));
        GetStuff();
    }
}

.

One side issue ...

(Note - For anyone using that sample code, don't forget Unity has no threading. Using Debug.Log is just a trick for that demo.)

The three "async" calls in the example happen on some other thread. Just as in Unity whenever you (say) start some calculation thread or use a plugin. When you get information "back" on those other threads, of course, you absolutely cannot access Unity again. (IE, you can't access any of the actual game objects, their component scripts, or the frame loop in any way in Unity). What you do is just "leave the information somewhere" for Unity to find. This is a basic of threading in Unity. (As explained at great length HERE for example.) Please note that in the example code above, I cheaply use "Debug.Log" (which you can use from any thread) as pseudocode.

\$\endgroup\$
  • \$\begingroup\$ I remember looking into that a while back but it was not an option since Unity used an ancient version of .NET that didn't include the WebSockets library. now with access to 4.6 that's no longer a problem and this is a pretty good option. It is a little bit lower level than the STA-Websockets but that could be a good thing depending on your needs. \$\endgroup\$ – Mattia Mar 28 at 14:27
  • \$\begingroup\$ how are you @Mattia . Right: indeed for client use (I mean, your unity app is a WS client) I can't see any reason you'd use anything else; it couldn't be simpler. So that's good news. I'm afraid, I have never tried having a WS server inside a Unity app, so I can't comment on that! :) Cheers! \$\endgroup\$ – Fattie Mar 28 at 14:29
  • \$\begingroup\$ This is a bit off topic but I thought Unity was single threaded? How do those asyncs work? Is there an exception for Tasks? Did they make things thread safe and I didn't notice. \$\endgroup\$ – Mattia Mar 28 at 17:42
  • \$\begingroup\$ @Mattia , (1) you basically have to use that async attribute if, in the function, you're going to await. Don't forget (2) while Unity itself is indeed a single thread, you can of course launch other threads. This is common for calculations, plugins or whatever. I am not really a top expert in C#, as such, but I believe when you attribute a function with "async" it indeed means that function will (essentially) run on another thread. As you point out, threads are utterly meaningless in calls in Unity components, so the call to "Connect", say, does indeed start a new thread, \$\endgroup\$ – Fattie Mar 28 at 18:15
  • \$\begingroup\$ , or at least, some sort of new aysnchronous operation courtesy of C#. Note that indeed, the information you get back you have to "transfer" to the main Unity thread. Exactly as explained here: stackoverflow.com/a/54184457/294884 Note that in the cheap example code above, I'm only using Debug.Log which you can shoddily run from anywhere, so yeah really in answer to your question the code as presented "wouldn't work" in Unity - you can't change anything in Unity from that other aysnc operation. (Debug.Log is a cheap shitty exception!) \$\endgroup\$ – Fattie Mar 28 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.