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

wss client without split #125

Closed
alex-shapiro opened this issue May 17, 2017 · 20 comments
Closed

wss client without split #125

alex-shapiro opened this issue May 17, 2017 · 20 comments

Comments

@alex-shapiro
Copy link

I'm upgrading from 0.17 to 0.19 and it looks like splitting a generic client (one that supports both WS and WSS) into its Sender and Receiver components is no longer possible because SslStream doesn't implement Splittable. Up to now splitting the client has been the idiomatic way to do things (at least in the examples) - is there a way around this limitation?

@illegalprime
Copy link
Collaborator

You cannot split SslStream into it's read and write components because of how SSL works.
Why not use the same client struct for both reading and writing? Or wrap it in a Mutex?

@alex-shapiro
Copy link
Author

Splitting the client into a Reader and Writer lets a program send and receive messages simultaneously, and as best I can tell, a single client struct cannot do that. If the client begins listening for incoming messages:

for message in client.incoming_messages() {
  ...
}

then it blocks the thread. Even if the client is wrapped in a Mutex, the resource is locked for as long as the client listens - if it listens for the lifetime of the program, other threads can't send messages at all.

@illegalprime
Copy link
Collaborator

You can use:

let message = client.recv_message().unwrap();
let _ = client.send_message(message);
.
.
.

If you want asynchronous stuff, that's coming very soon #6

@alex-shapiro
Copy link
Author

Ok, it seems like waiting for Tokio support is the best way forward.

@vi
Copy link
Member

vi commented May 18, 2017

Inability to split seems to be very restrictive: connection becomes half-duplex.

Why was it working before, in 0.18? Now it's even a problem to reply to pings.

@illegalprime
Copy link
Collaborator

@vi the previous implementation was wrong, you cannot have independent streams for reading and writing SSL. This is definitely a problem, but it's being addressed, are you familiar with tokio? Would you mind helping me figure it out?

@vi
Copy link
Member

vi commented May 19, 2017

@illegalprime, I tried building and running some Tokio example recently, but it's probably not enough to offer advice. Also not all parts of Tokio are stable enough.

Does Hyper and some ssl already support Tokio?


Looks like Tokio is the only sane (or insane) way to write actual networking apps for Rust, and it is "Not Ready for 1.0" now.

@illegalprime
Copy link
Collaborator

@vi yeah async stuff is crazy right now, I have a tokio example almost working, I'll publish it for clients as soon as I can!

@illegalprime
Copy link
Collaborator

@alex-shapiro @vi I just got the autobahn client tests passing for my tokio implementation, so it's coming along. You can try it out if you want on feat/tokio branch.

@vi
Copy link
Member

vi commented May 19, 2017

Can one use Tokio just to simulate splitting the SSL stream in two, without changing the entire application architecture?

@illegalprime
Copy link
Collaborator

@vi yes it can! I've already done it with a non SSL connection and there is no API difference I can tell with tokio-tls

@illegalprime
Copy link
Collaborator

In your opinion, do you think you should be able to use both sync and async apis or that turning one feature on should turn the other off? And any other API opinions would be welcome.

@vi
Copy link
Member

vi commented May 19, 2017

Before answering such questions I need to experiment a bit with the aforementioned example.

@illegalprime
Copy link
Collaborator

OK, take a look at that branch it should have a couple of examples right now.

@vi
Copy link
Member

vi commented May 20, 2017

Is it typical that Tokio examples are longer than usual synchronous examples?

@illegalprime
Copy link
Collaborator

In the autobahn they are longer, I'm also trying to figure tokio out and maybe there's a better way to do what I'm doing. Sometimes they can be smaller though, check out examples/async-client.rs.

@illegalprime
Copy link
Collaborator

@vi just realized I hadn't committed that file, it should be there now.

@illegalprime
Copy link
Collaborator

@alex-shapiro the tokio API is getting pretty stable, you can try it out if you want like OP did in #127 .
You would replace your websocket dependency with this in your Cargo.toml:

[dependencies.websocket]
git = "https://github.com/cyderize/rust-websocket"
branch = "feat/tokio"

@TomCrypto
Copy link

I've run into this issue as well with the sync client, does it actually make any sense to use a sync client with SSL since it's (allegedly) impossible to read from and write to it at the same time? If you are busy sending stuff you can never respond to messages, which wouldn't be such a big deal except that a client should normally respond to pings even if all it does is send. Seems to make the sync client essentially broken by design in most nontrivial cases, and forces the user towards the mess that is async...

@vi
Copy link
Member

vi commented May 23, 2018

Maybe you could just unsafely duplicate it and hope for the best?

(e.g. hope that some SSL re-negotiation won't be triggered while you are sending something)

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

4 participants