Open najamelan opened 4 years ago
Makes sense.
Indeed, previously we "did not notice" this problem as first versions of tungstenite-rs
did not allow to construct ping and pong messages directly.
@application-developer-DA are there any examples of how to manually construct a pong response? My use case requires that a pong is sent back with an internal message. From my understanding, this lib automatically returns an empty pong? Can it be overridden? thanks
@mycorrhizas
To send a custom pong message instead of the default pong message as a reply to a ping you can simply:
match socket.read_message()? {
Message::Ping(payload) => {
socket.write_message(Message::Pong(your_custom_pong_payload_vec_u8))?;
}
_ => {}
}
However, if you wish to keep sending the default pong message and send an additional pong you'd have to:
match socket.read_message()? {
Message::Ping(payload) => {
// Make sure default pong messages are not overwritten.
socket.write_pending()?;
// Additional pong here or anywhere else.
socket.write_message(Message::Pong(your_custom_pong_payload_vec_u8))?;
}
_ => {}
}
The RFC describes two uses for pong messages:
Tungstenite automatically replies to pings, and since the RFC defines that the application data should be identical to the ping, so there's not much the user can add to that. For that reason afaict a user should never manually respond to ping.
However the user can send pongs as unidirectional heartbeats. The problem is that right now by storing these on
self.pong
, they can override replies to ping, and potentially have different application data inside, so not constitute a valid response to ping.It's pretty unwieldy for client code to avoid this problem. If using tungstenite directly it can be avoided by following the reception of a ping by calling
write_pending
until it doesn't return wouldblock to be sure the ping has been answered and only then send a manual pong.If using through tokio-tungstenite or other code that splits reader and writer tasks, things become complicated, because now you have to communicate from your reader that received the ping that your writer should call
write_pending
before sending the next pong, and through tokio-tungstenitewrite_pending
isn't exactly accessible.I feel it would be better to document that a user should never respond to ping manually and consider user created pong messages like any other message to be queued. It doesn't need to jump the queue. The RFC only says replies to pings should be sent as fast as practical.
That would avoid this problem all together.