3
\$\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\$
1

3 Answers 3

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\$
6
  • \$\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\$ Feb 20, 2018 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\$ Jan 24, 2019 at 6:34
  • \$\begingroup\$ @bluejayke Nah, sorry, I didn't try this with 2018.3.2. My version was 2017.1. \$\endgroup\$ Jan 24, 2019 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\$ Jan 24, 2019 at 22:31
  • \$\begingroup\$ With this repo, I'm getting errors with .NET 3.5 \$\endgroup\$ Aug 16, 2019 at 13:49
10
\$\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.

Even more important, don't use my code above! :O

While my code is not wrong, it is not really complete. And there is a huge amount of work to do to really use WS from scratch.

The only current library is: https://github.com/Marfusios/websocket-client

We changed a very large project from "my" raw .Net code, to that library. (Alternately I would have had to basically .. rewrite that whole library!)

And here's what you have to do in Unity! You must use a ConcurrentQueue.

It is completely meaningless to process messages "instantly" in Unity: it is frame based!

Every arriving message: put it in a queue, and process them once each frame:

{Note that threading is irrelevant here. It makes no difference, at all, whether your processing that is getting the messages is on the "main" thread, another thread, many threads, or it is being handled by a quantum computer! Each message has to be queued in the frame system.}

someLibrary_aMessageHasArrived
    {
        incoming_messages.Enqueue( the message text );
    };

and ... this must of course be in a MonoBehavior ...

ConcurrentQueue<string> incoming_messages = new ConcurrentQueue<string>();
void Update()
{
    if (incoming_messages.TryDequeue(out var message))
    {
        Handle(message); .. your code for handling a message
    }
}

So that's what you do with real time messages to a Unity app. (Or any frame-based engine.)

\$\endgroup\$
14
  • \$\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, 2019 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, 2019 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, 2019 at 17:42
  • 1
    \$\begingroup\$ BUT WAIT! Like you, we avoided using libraries. (The "sharp" one, is in fact, pretty much dead now / doesn't work.) Pls, read the new part of my answer ! Depending on your needs, you may like us realistically need to use a library. (If so, this is the only working library ATM github.com/Marfusios/websocket-client ) \$\endgroup\$
    – Fattie
    Oct 7, 2020 at 19:03
  • 1
    \$\begingroup\$ @LachoTomov it would seem to me if it DOES work for you, that's good! I encountered problems with disconnections and so on .. overall we had top move to a library. It's a topuh business; I do not like using libraries myself, but, that's what we had to do in this case. Hope it helps in some way, sorry I don't have a "definitive" answer! \$\endgroup\$
    – Fattie
    Oct 8, 2020 at 10:26
1
\$\begingroup\$

2021 Answer: Another library which is also built on System.Net.Websockets like Fattie's linked Marfusios library, but is made for Unity is the following:

https://github.com/endel/NativeWebSocket

Contains a whole example which is quite simple to get up and running.

\$\endgroup\$
3
  • \$\begingroup\$ This is currently a link-only answer. You might want to consider posting it as a comment instead, or editing the answer to show a bit more detail about how to use this library. \$\endgroup\$
    – DMGregory
    Nov 20, 2021 at 21:54
  • \$\begingroup\$ @DMGregory Did the policy change since the primary answer was accepted? It is also a link-only. \$\endgroup\$
    – fallerd
    Nov 21, 2021 at 4:23
  • \$\begingroup\$ I did not happen to see that answer at the time it was posted, only three years later. In my experience, asking someone to flesh out an answer three years later rarely results in changes. But asking someone to improve a freshly posted answer sometimes successfully results in improvements. \$\endgroup\$
    – DMGregory
    Nov 21, 2021 at 14:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .