I wanted to understand the PStats protocol, since it is currently undocumented. I realised the best way to do that was to hack up my own implementation of a PStats server. I succeeded, and now I want to share my code for others to study, so that others can make their own PStats implementation if they wish.
The PStats protocol is actually quite simple. The client and server start the exchange by sending control messages over a TCP connection, with each control message prefixed with a 32-bit message length (excluding the length itself) and then an 8-bit message type, followed by the actual message data. All data is little-endian.
Afer the client connects, it sends a message identifying itself which includes a protocol version number. It also sends separate messages that identify all the available collectors and threads, both by unique index. (It keeps track of the ones it’s already sent, so that when new collectors or threads appear, it only sends the new ones.)
The server also sends a message identifying itself, but the server message contains a UDP port number for a UDP socket it opens. While control messages are always sent over TCP, the client can send frame data over either UDP or TCP (gracefully falling back to TCP if UDP fails). The UDP message format is slightly different; there is no length header, but there is a checksum, that is simply a 16-bit sum of all the message bytes.
Here is the code. It’s written in Node.js. You can just run
node index.js and then start up any Panda application with “want-pstats 1” (or shift+S in pview).