Message from Nodejs websocket to Unity

Hi, I’m a new user trying to make his first student project. I have a nodejs that is outputting the following message containg a list of players, whenever i invoke the method GetPlayersList(), which sends a request to my nodejs server.

{"type":"playersList","data":[{"id":"d995d5f4-b3ea-47e4-9c5c-310801a69edb","name":"mario","avatar":"avatar.png","score":0},{"id":"3782abe9-a0fe-405f-a681-a25ec984f95e","name":"luigi","avatar":"avatar.png","score":0},{"id":"fb27e65c-e960-4e30-a75e-7dc850bd0a9c","name":"rosy","avatar":"avatar.png","score":0},{"id":"f6d51e4d-d9ef-41ab-a26c-0fc09878412a","name":"mum","avatar":"avatar.png","score":0}]}

I’ve written a script called WebSocketManager (the file attached).

I can’t manage to memorize players in my playerList, I see it when my foreach cicle does not start and if I count the lenght of the list it says 0 players. Any help is appreciated…thanks in advance!

9444191–1325144–WebSocketManager.cs (5.63 KB)

Time to start debugging! Here is how you can begin your exciting new debugging adventures:

You must find a way to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the names of the GameObjects or Components involved?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: How To - Capturing Device Logs on iOS or this answer for Android: How To - Capturing Device Logs on Android

If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

If your problem is with OnCollision-type functions, print the name of what is passed in!

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

“When in doubt, print it out!™” - Kurt Dekker (and many others)

Note: the print() function is an alias for Debug.Log() provided by the MonoBehaviour class.

Networking, UnityWebRequest, WWW, Postman, curl, WebAPI, etc:

And setting up a proxy can be very helpful too, in order to compare traffic:

When you find more…

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: Using code tags properly

  • Do not TALK about code without posting it.
  • Do NOT post unformatted code.
  • Do NOT retype code. Use copy/paste properly using code tags.
  • Do NOT post screenshots of code.
  • Do NOT post photographs of code.
    - ONLY post the relevant code, and then refer to it in your discussion.

Hi and thanks for your reply! My attached script is full of debug messages, but I can’t find a way to figure out why the message is not parsed.

That’s because you can not just declare “data” as a string when it actually is an array. A deserializer does not simply keep the json as a string. Apart from that, even if that was possible, the JsonUtility can not deserialize json that has an array as the root element. It always has to be an object. So your general approach how you treat and parse your result just doesn’t work.

When using object mappers in a compiled language you often have issues how to parse variable json responses. In dynamic scripting languages that’s not really a problem since objects are just transparent on-the-fly created general purpose containers. This doesn’t work in C#.

You have several options here:

  • Parse the message several times. First only your “MessageData” type which should only have that “type” field, nothing else. Once you know the message type you can parse the whole response again with the correct class.
  • Use a more sophisticated parser which allows you to create custom parsing / conversion adapters. This way the parser itself could analyse the type field and create the right types during the parsing. Though this usually requires quite a bit of efford to setup properly. Also in the end you usually still need some sort of switch statement to handle the various cases.
  • Finally use a general purpose json parser that just parses the data into a dictionary / List structure of some sort. So it does not try to map the data to concrete object types but just stores them in a way you can access the data.

Newtonsoft’s Json.NET library can help you with both, the second and third option. I also have my own json parser SimpleJSON which is just a single c# file and provides easy access to the data without the need to create concrete classes. So that could be used for the third case as well. In fact I originally wrote the parser for Json web API access :slight_smile:

Example

        webSocket.OnMessage += (sender, e) =>
        {
            var n = JSON.Parse(e.Data);
            string type = n["type"];
            if (type== "playersList")
            {
                JSONNode playerList = n["data"];
                foreach (JSONNode player in playerList)
                {
                    Debug.Log("Player ID: " + player["id"].Value);
                    Debug.Log("Name: " + player["name"].Value);
                    Debug.Log("Avatar: " + player["avatar"].Value);
                    Debug.Log("Score: " + player["score"].AsInt);
                }

                string playerNames = "Nomi dei giocatori: ";
                foreach (JSONNode player in playerList)
                {
                    playerNames += player["name"].Value + ", ";
                }
                Debug.Log(playerNames);
            }
        };

Watch out. The JSONNode class has a ToString overload that turns this node back into json. So you don’t want to use “ToString” to get the value of a string field. The Value property or an actual implicit or explicit conversion into string would work. The class has many conversion operators to make it easy to use without the need of tons of casting. It’s also quite extensible. I do have some extension files that add easy conversion support for some of the Unity primitive struct types like vectors. Just have a look at the repository. Extension files just need to be dropped right next to the SimpleJSON.cs file.

Thanks for your reply. I will try this for what my little understandings are…
Btw even chatgpt suggested me your github repo :slight_smile: but I’m a real noob that does not understand how to use things…I just started using unity less than a month ago and I have 0 programming skills prior to that.

Really? that’s crazy :smile:

Btw, I edited my answer and added an example usage. Don’t forget the using SimpleJSON; at the top.

Yes, It’s real! Even Llama2 knows your repo:

"
do you knowthis repo?
https://github.com/Bunny83/SimpleJSON/tree/master

:::::::

Yes, I’m familiar with the SimpleJSON repository on GitHub. It’s a popular JSON parser and generator library for C#, developed by Bunny83.

The library allows you to parse JSON data from a string, file, or stream, and also provides methods to generate JSON data from C# objects. It’s designed to be easy to use, fast, and lightweight, making it a good choice for a wide range of applications.

The repository includes a number of useful features, such as support for JSON arrays, objects, and primitives, as well as error handling and parsing options. It also includes a number of examples and unit tests to help you get started and ensure that the library is working correctly.

Overall, SimpleJSON is a useful library for anyone working with JSON data in C#, and it’s well-maintained and actively developed by the community.
"

Your solution in the example worked like magic! I used your simplejson git, downloaded the code as zip, exctracted in my script folder, modified with your example the code, added using simplejson; , changed the message data as follows:

public class MessageData
{
public string type;
public List data;
}[/code]

really thank you for your awesome help!

9444371–1325177–WebSocketManager.cs (5.06 KB)