wpilibsuite / ntcore

NetworkTables Core Library (ARCHIVED, merged into allwpilib)
Other
39 stars 28 forks source link

Implementing a way to send Server connection info #57

Open ThadHouse opened 8 years ago

ThadHouse commented 8 years ago

One thing I had been thinking about was it would be nice if clients could get information on all the clients connected to the server. One big use case for this is we could print all the connected clients to a widget on the smart dashboard, and we could see if coprocessors connected properly. I can think of a few ways to implement this, and was wondering which one seems the best.

  1. Implement a new Message type, that whenever a new client is connected to the server it sends new connection info to new clients. This would be the hardest to implement and most invasive, but cleanest in the long run.
  2. Send the data over its own NetworkTable value using Raw type. This is actually fairly easily to implement in the NetworkTables code, but we could also potentially add this to WPILib as well if we don't want to pollute NetworkTables.

If we do either of these, it would be nice to have a prebuilt SmartDashboard widget that could read these.

Would either of these be a good idea, or would there be a better way to implement this?

333fred commented 8 years ago

I like the idea of number two more, tbh. We could designate a subtable for connection info, and introduce a section in the spec that says clients must create/update a key that corresponds to them on startup. The server then deletes/changed a connection status to disconnected when it detects that client is disconnected. The hard part, to my mind, will be persistently identifying clients.

ThadHouse commented 8 years ago

I was thinking it would be even easier then that. Since the server already has all the connection info you would need anyway, every time a connection listener fires, grab a new list of all clients and update the value of the connection key on the server. That will then get sent out to all the clients. The server also knows if the client has been connected or disconnected, and that can be added to the connection data sent over. I actually have most of this implemented at home already, and its only like 30 or so lines of code to add it.

I think sending 1 raw binary key would be easier then a subtable for connections, then a subtable for every individual connection. It means something like Outline Viewer would have a hard time parsing the data, but we can add a new GetServerConnections() method that would get a list of all the connections to the server, and clients could then loop though that, similar to how a server now can loop though GetConnections().

PeterJohnson commented 8 years ago

I'd like to provide a standardized way to do array-of-struct (see #58), which could be used to simply provide a copy of the server's ConnectionInfo array in a standard connection key. (I would also like to see GRIP use this method to avoid the atomic update problem they currently have when using multiple arrays).

ThadHouse commented 8 years ago

That would definitely be cool, and basically what I'm doing manually, but if it was automated that would be even better. The only part I was having trouble with was figuring out where to detect a connect and disconnect and resend the data. Dispatcher has ways to detect connections, but not to detect disconnection. In notifier, you can detect both connections and disconnections without actually starting the notifier loop, however, that would end up with a cross dependency with either Dispatcher or the nt::SetEntryValue function, which might not be the best idea. The 3rd way to add it is that when run on the RoboRIO, since every class basically creates a table listener, notifier is always running anyway, so we can just add a regular connection listener whenever StartServer is called, and remove it when StopServer is called. I think the 3rd way would end up being the least intrusive way of doing this.