Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client should reply to ping with pong containing the same data as the ping #100

Closed
nastynaz opened this issue Jan 13, 2024 · 3 comments
Closed

Comments

@nastynaz
Copy link

Problem

The Websocket spec states that:

"a Pong frame sent in response to a Ping frame must have identical 'Application data' as found in the message body of the Ping frame being replied to." - source.

This means every ping received by the client should result in a pong reply with the same bytes as the received ping.

I don't see anywhere in the codebase where this is implemented.

Potential solution

I am happy to fix this and make a PR, however I'd like to know where people think the best place to handle it is.

Should the pong reply happen at the Socket level so that it is abstracted away from the client? If so, should the user be able to specify a closure to handle the payload much like they can with the heartbeat?

Or should new Message::Ping(bytes) and Message::Pong(bytes) be created and on_ping and on_pong be added to the client (with default implementations) to allow the user to decide how they want to reply?

Open to all suggestions and ideas.

@gbaranski
Copy link
Owner

Hey!
Thanks for your interest :)

I strongly believe that the Pong are being sent by tungstenite, I cannot see any reference Pong message being sent in our code.

To verify I tried changing the default SocketConfig for server connections to this:

             Acceptor::Plain => {
                let socket = tokio_tungstenite::accept_hdr_async(stream, callback).await?;
                Socket::new(
                    socket,
                    SocketConfig {
                        heartbeat: std::time::Duration::from_secs(5),
                        timeout: std::time::Duration::from_secs(10),
                        heartbeat_ping_msg_fn: std::sync::Arc::new(|_| {
                            crate::RawMessage::Ping(vec![1, 2, 3, 4]) // <--- send custom ping message
                        }),
                    },
                    handle.clone(),
                )
            

And it ended up in server receiving the same vec![1, 2, 3, 4] from the Client as Pong message.

RUST_LOG=ezsockets=trace cargo run
   Compiling ezsockets v0.6.1 (/Users/gbaranski/code/ezsockets)
   Compiling ezsockets-chat-server v0.1.0 (/Users/gbaranski/code/ezsockets/examples/chat-server)
    Finished dev [unoptimized + debuginfo] target(s) in 1.30s
     Running `/Users/gbaranski/code/ezsockets/target/debug/ezsockets-chat-server`
2024-01-13T22:41:47.398175Z  INFO ezsockets::server: starting websocket server
2024-01-13T22:41:48.450214Z  INFO ezsockets::server: connection from 127.0.0.1:58913 accepted
2024-01-13T22:41:53.451781Z TRACE ezsockets::socket: sending message: Ping([1, 2, 3, 4])
2024-01-13T22:41:53.453302Z TRACE ezsockets::socket: received message: Ok(Pong([1, 2, 3, 4]))
2024-01-13T22:41:58.454708Z TRACE ezsockets::socket: sending message: Ping([1, 2, 3, 4])
2024-01-13T22:41:58.456440Z TRACE ezsockets::socket: received message: Ok(Pong([1, 2, 3, 4]))
2024-01-13T22:42:03.458585Z TRACE ezsockets::socket: sending message: Ping([1, 2, 3, 4])
2024-01-13T22:42:03.460073Z TRACE ezsockets::socket: received message: Ok(Pong([1, 2, 3, 4]))
2024-01-13T22:42:08.460316Z TRACE ezsockets::socket: sending message: Ping([1, 2, 3, 4])
2024-01-13T22:42:08.461484Z TRACE ezsockets::socket: received message: Ok(Pong([1, 2, 3, 4]))
2024-01-13T22:42:13.461751Z TRACE ezsockets::socket: sending message: Ping([1, 2, 3, 4])
2024-01-13T22:42:13.462815Z TRACE ezsockets::socket: received message: Ok(Pong([1, 2, 3, 4]))

If you mean that you want to configure the Ping being sent from the server - I have opened an issue for this #101.

I'm closing it for now, feel free to reopen if you have any more concerns regarding this topic :).

cc @UkoeHB

@UkoeHB
Copy link
Collaborator

UkoeHB commented Jan 13, 2024

On native tungstenite will automatically send a Pong when it receives a Ping. WASM clients need to manually send Pongs (e.g. with a Text-based custom protocol).

The client/server socket can be configured to send custom Pings already, with SocketConfig::heartbeat_ping_msg_fn.

@gbaranski
Copy link
Owner

The client/server socket can be configured to send custom Pings already, with SocketConfig::heartbeat_ping_msg_fn.

That right, but AFAIK there's no way to pass SocketConfig to a server right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants