7.1 KiB
Versioning
Proto Socket tracks protocol compatibility separately from language package versions.
Current Versions
- Protocol version:
0.1 - Dart package version: see
dart/pubspec.yaml - Go module version: repository tag based
0.1 is the current compatibility contract for the checked-in available implementations. The wire format does not carry a protocol version field yet; compatibility is verified by shared proto definitions, unit tests, and cross-language tests.
Protocol 0.1 also allows optional application-level convention messages for capability announcement and request error reporting. These conventions do not change the required handshake or the PacketBase wire fields unless they are promoted in a later protocol version.
Protocol Version
The protocol version describes the wire-format and behavior contract that every language implementation must satisfy:
- TCP uses a 4-byte big-endian payload length followed by one
PacketBaseprotobuf payload. - WebSocket and WSS use one binary frame per
PacketBaseprotobuf payload. PacketBase.typeNameroutes the inner message by canonical protobuf full message name.nonceincrements for every outbound packet on a connection.responseNoncelinks a response packet to the request nonce.- Heartbeat behavior follows
PROTOCOL.md.
Breaking protocol changes require a new major protocol version. Backward-compatible additions keep the same major protocol version but must include updated tests before release.
Proto Package and Wire Identity
Proto package names are part of the wire identity because they prefix protobuf full message names. Package names must use lowercase snake_case segments joined by dots, for example proto_socket or example_chat.v1.
The canonical package for the shared packet schema is proto_socket. Common message identities therefore use values such as proto_socket.PacketBase, proto_socket.HeartBeat, and proto_socket.TestData; PacketBase.typeName carries the inner message identity.
Language-specific namespace options such as Go go_package or Java/Kotlin package names are package-generation details. They do not change the protocol package or wire typeName.
Git Release Standard
Current consumption and release flow is Git ref/tag based. Package registry publication is optional future work, not the current release standard.
Git releases must identify the repository ref/tag being consumed and use the full local validation matrix as the compatibility gate.
Package Version
Each language implementation may publish on its own package cadence if registry releases are later introduced. Package versions communicate implementation releases, bug fixes, and language-specific API changes.
A package release must state which protocol version it implements. A package version bump does not imply a protocol version bump unless the wire-format or required behavior changes.
Breaking Protocol Changes
Examples of breaking protocol changes:
- Renaming or removing
PacketBasefields. - Changing the canonical proto package or
typeNamederivation without a compatibility path. - Changing
nonceorresponseNoncesemantics. - Changing heartbeat request/response timing or echo behavior in a way that disconnects older peers.
- Changing TCP framing, byte order, max packet handling, or WebSocket binary-frame rules.
Non-breaking Protocol Changes
Examples of non-breaking changes:
- Adding a new protobuf message type.
- Adding optional fields to application messages when older peers can ignore them.
- Adding a new language implementation that passes the existing protocol and cross-language tests.
- Tightening tests or documentation without changing wire behavior.
- Adding an optional hello/capability message that peers may ignore and that is not required before normal traffic.
- Adding an optional standard error response convention, provided older peers can still fail by timeout or existing response type-mismatch behavior.
Backward-compatible message additions require updated parser maps and cross-language tests before release.
Optional Capability Announcement
ProtoSocketHello, or an equivalent project-specific message, is a candidate convention for announcing:
protocolVersion- stable
capabilitiestokens - optional implementation metadata
In protocol 0.1, this message is not a required handshake. A peer must be able to send and receive normal messages without first receiving a hello/capability message. Making a hello message mandatory, changing connection readiness semantics, or disconnecting older peers that do not send it requires a protocol-version review.
Standard Error Response Convention
ProtoSocketError, or an equivalent project-specific message, is a candidate convention for request handler failures. A supported error response should carry the original request nonce in responseNonce, a stable error code, a safe message, and optional detail/debug fields.
In protocol 0.1, implementations may continue to report handler failure as timeout, response type mismatch, or implementation-specific errors. Requiring all handlers to emit a shared error response, or requiring every requester to treat a particular error message type specially, requires parser map updates, cross-language tests, and compatibility review.
nonce Overflow
nonce and responseNonce fields are protobuf int32 values (signed 32-bit).
The maximum emitted nonce is 2,147,483,647 (int32 max).
Current policy:
- Implementations start at
1and increment by1on every send call, including requests and responses. - When selecting the next nonce to emit, implementations must skip any value that is currently used by an active pending request (
sendRequestcorrelation map). This keeps nonce reuse from colliding with in-flight requests after wrap. - If all positive
int32nonce values are currently pending,sendRequest/sendmust fail explicitly rather than emit a duplicate correlation nonce. - After issuing
2,147,483,647, implementations reset the internal counter to0; the next emittedPacketBase.nonceis1. 0is reserved and must not be emitted asPacketBase.nonce, becauseresponseNonce == 0means "not a response".
Changing this wrap behavior or the reserved meaning of responseNonce == 0 changes nonce semantics and requires compatibility review and cross-language boundary tests.
New Language Compatibility
A new language implementation must target the current protocol version unless its README explicitly says otherwise. Before it is listed as available, it must:
- Generate protobuf bindings from the canonical schema.
- Use the same canonical protobuf full message name
typeNamevalues as the available implementations. - Keep language namespace/package options separate from the protobuf package used for wire identity.
- Implement TCP, TLS+TCP, WS, and WSS framing consistently where the language runtime supports them.
- Implement request-response correlation with
nonceandresponseNonce. - Handle heartbeat automatically inside the client/server core.
- Pass same-language tests and cross-language tests against at least one available implementation.