Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define the network protocol #5

Open
elegaanz opened this issue Feb 17, 2021 · 3 comments
Open

Define the network protocol #5

elegaanz opened this issue Feb 17, 2021 · 3 comments
Labels
area: server documentation Improvements or additions to documentation help wanted Extra attention is needed

Comments

@elegaanz
Copy link
Contributor

Which transport? Which encoding? that kind of questions

@elegaanz elegaanz added this to the First prototype milestone Feb 17, 2021
@elegaanz
Copy link
Contributor Author

How do we version the protocol too, very important IMO.

@elegaanz elegaanz added area: server documentation Improvements or additions to documentation help wanted Extra attention is needed labels Feb 17, 2021
@edgarogh
Copy link
Member

(A packet is essentially a big sum type where each variant is a different packet type.)

Suggestions:

  • message-io creates a stream of objects of a specific type, uses serde to read/write to sockets and is transport-agnostic (supports TCP, UDP and WS and can be adapted to other ones)
    • Problem: 🚫 No 🔝 migrations 🗃️what-❓-so-🤔-ever⏲️
      More specifically, most efficient serde De·Serializers (:wave: bincode) only use the enum's ordinal discriminator to differentiate them. They also consider the fields of structs to be in a stable order. With serde, there's no way of adapting this kind of things to a slightly different breaking version. A rather good solution though, would be to introduce a network_types crate that we strictly semver, and intentionally include multiple versions of it (with aliases). Then we implement From<T> for each struct of each version... Macros would be useful here.
  • A custom protocol. First of all, if we expect it to be slightly unreliable (not in the UDP sense, as in stability between versions), then we make a basic framing system, so it's easy to know when a message begins and ends even if we don't know its structure (and we can recover from it without restarting the connection). This framing protocol must support splitting messages in small parts, so 1) the stream can be multiplexed to accommodate plugins 2) long messages don't literally lock the the channel.
    Then we need to think about how the different messages' type are identified: a static numeric ID (like the ordinal enum discriminator above) is not great for versioning, but it's also hard for plugins to introduce their own packets (they'd have to be included inside an enum variant OR we'd use unsafe code to "use" the remaining available discriminators). I didn't really think much about it but maybe the best way to do this is a complex handshake where numeric IDs are allocated from plain text IDs+version ? (I'm pretty sure Minecraft/Forge does a bit of both. Named channels can be opened by the base game or mods, and then they implement their own packets and packet IDs without any fear of collision). Needs more elaboration

And we should definitely create a different Packet enum for client-bound / server-bound packets, it's much safer and actually much simpler.

@elegaanz
Copy link
Contributor Author

We discussed this a bit more privately, and here are our conclusions so far:

  • the underlying protocol will be websockets, because they provide framing, and we get security for free with wss://
  • when connecting, the server sends a "map" from numbers to message types
  • we discussed about a few basic messages and authentication too, but I'll write what we said in a proper document

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: server documentation Improvements or additions to documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants