On 15/10/2019 04:47, Michael Pittaro wrote:
I've been playing around with the UDP server capability in wsjt-x, and I think I've got most of the lower level details figured out. However, I got blocked on the schema negotiation part, which raised a deeper question.

I have been assuming wsjt-x is a server, and my code is a client.  So I sent heartbeats like a client, and I was expecting some sort of response back, which never arrived.  I definitely see traffic (heartbeats, decodes, status, etc.) from wsjt-x, using the WSJT-X client id.

Digging deeper, it seems wsjt-x is acting more like a client.  The docs also imply that.  For example, The location message is described as in, allowing a 'server' to set the location.  Logged ADIF is described as out, being sent to servers when a QSO is logged. The example message aggregator is also a server, listening to wsjt-x and other clients.

I think I'm just missing something obvious here in terms of the frame of reference for client and server, and what the client/server model looks like.  Should my code act like a client or a server?

So far, I'm I'm using unicast, with just wsjt-x and my code running.

mike, kj6vcp


Hi Mike,

the terminology of client and server are somewhat loose in UDP protocols but with the WSJT-X UDP protocol WSJT-X is definitely a client and any application wishing to interoperate with WSJT-X is a server. The interoperating application should listen on a well known address and port which is the address and port configured in one or more instances of WSJT-X via "Settings->Reporting->UDP Server", i.e. many WSJT-X instances (clients) interoperate with one (or more, see below) servers listening on well know address and port pairs.

With unicast UDP there can only be one server per address and port pair (UDP broadcast does not have that limitation but has other severe routing limitations that make it unsuitable for the WSJT-X protocol), this is a fundamental limitation of IP addressing and information transport. WSJT-X expects servers to implement multicast group UDP address membership, this removes the limitation of there only being one server per address and port pair. Unfortunately almost all applications that have so far been written to interoperate with WSJT-X have failed to implement multicast group membership which means that they are not good citizens in the WSJT-X protocol because they consume messages that would be sent to all multicast group members. This means that using such an application precludes other applications joining the party without over-complex, and only partially successful, message forwarding arrangements.

The reference applications provided with WSJT-X (message_aggregator and udp_daemon) do support multicast group membership and can be easily used to demonstrate the protocol working with multiple WSJT-X instances *and* multiple interoperating sever applications. To do this simply set the UDP server address in all WSJT-X instances to a multicast group address of suitable scope, e.g. 239.255.0.0 will work on the local sub-net which includes multiple servers and clients on a single host. The service port number choice for multicast is no different than for unicast and the default 2237 is fine so long as no unicast servers within the scope are listening on that port. With message_aggregator the multicast group address is set in the UI, with udp_daemon it is a command line argument (use the -h command line option for usage information).

With respect to Heartbeat messages, they are bidirectional but not required in the server to client direction, currently the only action is taken by WSJT-X on receipt of a Heartbeat message is initial schema negotiation, other than that they only keeping the protocol alive by informing that the server is still alive and kicking. Servers can choose to send regular Heartbeat messages to each client they are aware of but it is not a requirement, sending Heartbeat messages at 15 s intervals would not be unreasonable if servers choose to do so. Note that traffic from servers to clients is not multicast since all messages to clients are specific to that client. Traffic sent from servers shall be sent to the sender address and port pair gathered from a prior message receipt  from the client, this is normal IP messaging as used by any server application serving content to a client. WSJT-X instances do not listen on the multicast group address, that is the role of the servers.

With respect to the schema number, firstly the schema number does not define the message types or fields, it is there to define the low level serialization of field contents on the wire. The schema number will only be incremented if we need to include a new field data type that is not defined by the current schema and that in turn is defined by the Qt serialization formats for the Qt types that we use on the wire. I should add that more than one application developer has claimed that the use of Qt serialization formats precludes them from consuming the WSJT-X UDP datagrams, this is not correct as the serialization formats are straightforward industry standard ones for compact binary data, i.e. we have to choose some "on the wire" format and Qt is particularly convenient and efficient but easily consumed by non-Qt applications.

With respect to schema negotiation, it is a requirement of the WSJT-X UDP protocol that servers and clients written at different times interoperate correctly. To do so any node whether it be client or server can expect to only receive messages using the schemas that were known at the time the application was written (or updated). The consequence of this, particularly in a multicast grid like topology where there may be multiple clients *and* multiple servers all communicating on the same multicast group address and service port number, is that all nodes must be prepared to degrade to an older schema number if an application joins the party that knows nothing about the currently negotiated schema. This negotiation is done when an application receives it's first Heartbeat message. That Heartbeat message will contain a schema number (all messages do), and a maximum schema number. The server shall not send any messages with a schema number greater than the number received in the first message from a client. The server may use a lower schema number if it was not written at a time the received schema was specified, that will negotiate the lower schema number with the client. Once a lower schema number is negotiated that schema number will propagate across all active nodes this allowing communications to continue without issue other than certain messages using field types only defined in the discarded schema will not be sent any more. This necessary degradation of the UDP protocol messages is unavoidable so interoperating application developers should make efforts to track schema updates with new versions, note that these schema updates will be very rare.

73
Bill
G4WJS.

_______________________________________________
wsjt-devel mailing list
wsjt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wsjt-devel

Reply via email to