Binary Serialisation and networks

As per a quick disscusion on the forums, I’ve had an issue sending a datatype via zMQ from one PC to another. Working in 2021.3 but not in 4. I see it is becuase because they now recompile all the time. As a workaround, I tried using the .dll from the .vl folder, and also from the exported app for the remote senders, both drag and dropping and linking as an external dependancy file, but no joy. So whats my best solution, it could be using json or similar, but how to turn that into bytes in as effecient a manner, as my remote pc’s are low powered due to heat issues in the install, binary is good, as it spits out bytes as default! :D It would be great if we could take a .dll in from a compiled app, and use it unmodified in another app.

In latest 2021.4 previews we use a different compiler strategy to improve the patching performance in bigger projects (see my reply here). That strategy requires certain indirections in the target code. On export those indirections are not needed and won’t be generated. A patch running inside the editor therefor has a slightly different binary representation than one running as an exported application.

We’ll need to think of some sort of options on the document/patch level to be able to enforce binary compatibility. Or not introduce the indirection at all on classes/records. Not sure yet, will need some internal discussion. Thanks for brining it up.

1 Like

Any thoughts of a work around for the short term?

you could write your data classes, the ones you want to send over the network, in C#. that way they will stay the same.

or go more low-level and only send spreads/arrays of primitive types, like Vector3, Matrix…

And using our serializer is not an option? It’s not as fast but is this really the bottleneck in the end?

@Elias that was another part of my question, how to turn a string into a byte array that mq will take, for each and char to byte seemed really slow when I tried.
Which serialiser adds the fewest padding text?

ToBytes and FromBytes in the string category.

The publish/subscribe help patch inside the VL.IO.NetMQ package shows you how to turn a string into a byte array suitable for sending (ToBytes and FromBytes nodes).

So my suggestion you could try is the following:
Sender: Serialize [Serialization] -> ToString [XML] -> ToBytes [String] -> ZeroMQ
Receiver: ZeroMQ -> FromBytes [String] -> Parse [XML] -> Deserialize [Serialization]

Oh and ensure that you set Include Defaults on the Serialize node to true as that seems to make a big difference performance wise.

1 Like

we also had the problem of serialzing for netowork a few months ago in a project and convenience highly depends on how much data you want to send each frame.

the XML path + parsing can beocme quite slow and needs higher bandwidth. but it works fine for a few small objects, it only becomes a problem if you have hundrets or even thousands of objects every frame it becomes the bottleneck quickly. also, our app started to freeze now and then because if the memory that the spreads and conversion operations create every frame becomes bigger than a certain size, the runtime will use a different memory area that is expensive to clean.

so just test it and depending on the amount of data, you might have to go more low-level and directly send the bytes of a vector array and put the data back into your objects on the other side.

if we can solve the binary compatibility in the new branch, then we would have a nice middle ground for slightly higher data amounts, that are not extreme.

1 Like

On another project at the moment, so I’ll get back to you when I’m home!

Binary serialisation runs at around 9000 micro seconds on the tiny pc, xml and json at 80,000, which is how I ended up with binary I seem to remember now!
I’ll see if I can work out how to make a class in c#, chances are minimal, expect questions! :D

this should get you started: Writing nodes using C# | vvvv gamma documentation

Ok… So I need to add Stride.Core.Mathematics to be able to use vectors, added it via nuget but then

Then I guess I change floats to vectors,
My input should be a spread i guess, but what am I returning? a spread ? or an object?
I’m lost already (there is a reason I chose visual patching, its called dyslexia, even reading the simple help page is disorientating, even with English as a first language!)

You don’t have to return anything basic serialiseble deserialiseble class would be:

public class MyData
    public float MyFloat;
    public Vector3 MyVector; 

Ok, weird, but I can live with that! How do I get stride nuget to work, as I can’t make a vector3 without it! and would it need to be an IEnumerable < Vector3 > ?
Accoring to this, the package should be accessible straight away…

@catweasel i have a simple idea. you can just use the preview before the merge of the new proxies branch. that will have binary compatibility and TextureFX should work:

For reference: latest previews should fix this issue - the binary serializer (based on FSPickler) is now aware of the indirection and will skip it accordingly. It no longer matters whether running inside the editor or running as an executable, the serialized output will be the same.

It will also use VL defined type names and resolve them as such - this should help in boygroup scenarios when changing the patches on one machine and reloading the patches on other machines.
Since we also got a request where one part of a system is running in beta and another in gamma we’ve backported the new serializers into a 2021.3 compatible package called VL.CoreLib.Backports.


Sorry for bringing this up again - I’m running into exactly this problem in 21.4.8:
Binary serialization of a datatype works fine for me when sending editor → editor and export-> export.
However, when sending from export → editor I do get exceptions with the Deserializer.

Is this expected behaviour?

Assuming they’re running the same version, I’d say no, not expected. Can you provide a patch?

Upon closer inspection it is the serialization of a Spread<MyDataType> that causes the problems.

I made a mininmal patch-set to reproduce:

  • Datatype.vl → Definition of MyDataType
  • MyDataTypeSender.vl → Serializes and sends a Spread<MyDataType> via NetMQ. Export this as .exe to create a console-app that sends
  • MyDataTypeReceiver.vl → Deserializes this and throws exceptions upon Deserializing if the sender is the .exe but works fine when the sender is running in the editor. (9.9 KB)