Remix.run Logo
mgaunard 6 hours ago

It's 2026 and I'm still defining my own messaging and wire protocols.

Plain C structs that fit in a UDP datagram that you can reinterpret_cast from is still best. You can still provide schemas and UUIDs for that, and dynamically transcode to JSON or whatever.

bluGill an hour ago | parent | next [-]

Until you have to work with big and little endian systems. There are other weirdness about how different computers represent things as well. utf-8 / ucs-16 strings (or other code pages). Not all floats are ieee-754. Still when you can ignore all those issues what you did is really easy and often works.

pjc50 an hour ago | parent | prev | next [-]

Provided that:

    - you agree never to care about endianness (can probably get away with this now)

    - you don't want to represent anything complicated or variable length, including strings
benterix 6 hours ago | parent | prev [-]

If you decide to use UDP, do you ignore the transmission errors or write the handling layer on your own?

mgaunard 6 hours ago | parent [-]

I handle it in different ways by topic.

For topics which are sending the state of something, a gap naturally self-recovers so long as you keep sending the state even if it doesn't change.

For message buses that need to be incremental, you need to have a separate snapshot system to recover state. That's usually pretty rare outside of things like order books (I work in low-latency trading).

For requests/response, I find it's better to tell the requester their request was not received rather than transparently re-send it, since by the time you re-send it it might be stale already. So what I do at the protocol level is just have ack logic, but no retransmit. Also it's datagram-oriented rather than byte-oriented, so overall much nicer guarantees than TCP (so long as all your messages fit in one UDP payload).