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

Non-blocking WebSocket polling #140

Closed
randomPoison opened this issue Jun 6, 2017 · 9 comments
Closed

Non-blocking WebSocket polling #140

randomPoison opened this issue Jun 6, 2017 · 9 comments

Comments

@randomPoison
Copy link

Related to #137, would it be possible to have a non-blocking variant of WebSocket::next? The idea would be the same as Receiver<T>::try_recv, it returns the next message if there is one ready, but returns without blocking if there are none. Without this functionality, it seems like it isn't possible to do something like have a thread wait for either a WebSocket or another channel.

I took a brief look at the implementation of WebSocket::next and it looks like its the underlying Box<ReadWrite>::read implementation that blocks waiting for data from the socket. Given that rouille is built on tiny_http, would it even be possible to implement a non-blocking read from the socket? Also, is it possible that I'm completely off-base in thinking that it's not possible to wait on both a WebSocket and another channel?

@tomaka
Copy link
Owner

tomaka commented Jun 6, 2017

would it even be possible to implement a non-blocking read from the socket?

The answer is probably no.

@randomPoison
Copy link
Author

Ah, that's a shame. Do you have a sense of whether that would be because of how tiny-http is implemented, or because of how the underlying OS handles sockets at a fundamental level? I'm not personally experienced working with sockets in general.

@mleonhard
Copy link

I need this.

@bradfier
Copy link
Collaborator

bradfier commented Oct 4, 2021

I need this.

I haven't had time to poke around in the WebSockets code other than to do some refactoring on the byte order bit twiddling. As a result I don't have a view on how complex (or even possible) this will be to implement.

Of course things have changed since 2017 when Tomaka looked, so it's possible it can be done now.

I would accept patches to enable a non-blocking call if you're interested in implementing it.

@gwbres
Copy link

gwbres commented Jun 6, 2022

@randomPoison, @bradfier,
try_recv() and recv_with_timeout() are natively supported, since the websocket stream is a channel
https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html

@randomPoison
Copy link
Author

Okay, thanks for the follow-up. I'm no longer using rouille so I will close this issue. Feel free to reopen if needed though!

@mleonhard
Copy link

mleonhard commented Jun 9, 2022

@gwbres I think there's a little mixup. This issue is about polling for new messages. When setting up a new connection, you call rouille::websocket::start and get a std::sync::mpsc::Receiver<Websocket> struct. You can poll that Receiver and get the rouille::websocket::Websocket struct. But then there is no way to poll the Websocket struct for new messages sent by the remote client. This means that a server that wants to receive websocket messages must use a thread per connection. That scales poorly.

I also stopped using Rouille because of this and other scaling problems. I wrote a new webserver that should scale better: beatrice.

@gwbres
Copy link

gwbres commented Jun 9, 2022

@mleonhard that is totally correct, this approach requires one thread per connection

@bradfier
Copy link
Collaborator

Any modern server should easily handle thousands of threads if you need one per connection, if your requirements are an order of magnitude or two above that, then an Async framework will definitely be the way to go instead of using Rouille and it's synchronous approach.

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

5 participants