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

Does not detect connection close in double-listen configuration #183

Open
masto opened this issue Apr 3, 2023 · 3 comments
Open

Does not detect connection close in double-listen configuration #183

masto opened this issue Apr 3, 2023 · 3 comments

Comments

@masto
Copy link

masto commented Apr 3, 2023

Probably easier to demonstrate than explain. If you proxy a listening websocket to a listening TCP socket:

$ websocat ws-l:127.0.0.1:5818 tcp-l:127.0.0.1:5819

and then connect to the websocket and close the connection, it won't notice. Opening another connection results in:

[INFO  websocat::net_peer] Incoming TCP connection from Some(127.0.0.1:53318)
[INFO  websocat::sessionserve] Serving 1 ongoing connections
[INFO  websocat::ws_server_peer] Incoming connection to websocket: /
[INFO  websocat::ws_server_peer] Upgraded
<<<at this point, the first connection is terminated, but websocat doesn't notice>>>
[INFO  websocat::net_peer] Incoming TCP connection from Some(127.0.0.1:39270)
[INFO  websocat::sessionserve] Serving 2 ongoing connections
[INFO  websocat::ws_server_peer] Incoming connection to websocket: /
[INFO  websocat::ws_server_peer] Upgraded
websocat: Address in use (os error 98)

If you connect to the TCP socket, it then immediately prints

[INFO  websocat::ws_peer] Received WebSocket close message
[INFO  websocat::sessionserve] Forward finished

This behavior doesn't occur if, for example, it's in plain server (-s) mode, or using tcp:, literalreply:, etc. It seems specific to proxying to a listening port with nothing connected.

Expected behavior is that when the websocket connection is closed by the client, the websocat server should close the other side and become ready to serve again.

@vi
Copy link
Owner

vi commented Apr 3, 2023

Specifying listeners on both parts is typically not a good idea. What do you want to do?

Some things that may help:

  1. Specifying -E option to terminate connections more aggressively;
  2. Using reuse-raw: overlay (or maybe reuse-broadcast:, depending on use case);
  3. Using autoreconnect: (especially with some form of connection reuser).

Command line that works reasonably for me:

websocat --text -E ws-l:127.0.0.1:5818 reuse-raw:autoreconnect:tcp-l:127.0.0.1:5819

Note that port 5819 only starts being listened after the first WebSocket clients gets connected.

@masto
Copy link
Author

masto commented Apr 3, 2023

Thanks very much for those overlays. I'd tried -E before with no luck, but using the options you suggested together seems to do the trick.

What I'm doing is, specifically, https://nabu.run (https://youtu.be/zabJhYvoI1k). It may not be a good idea to listen on both parts, but it is exactly what I need. Being able to do that with websocat makes my application possible, and saves me having to write my own proxy.

The situation I was trying to avoid was that if you clicked the "Connect WebSocket" button and then closed it or reloaded the page, it couldn't be used again.

Not sure if there's still a bug worth fixing, but I feel like I have a reasonable workaround now.

@vi
Copy link
Owner

vi commented Sep 17, 2023

If you want to listen WebSocket from both sides then maybe you want to use wsbroad as a component.

Websocat may still be needed to turn tcp-l:127.0.0.1:5819 into a connection to wsbroad, but overall it may be more flexible.

reuse-raw may correspond to wsbroad's --backpressure[-with-errors] option.

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

2 participants