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

Should server example using coroutines be added? #144

Open
vi opened this issue Sep 17, 2017 · 7 comments
Open

Should server example using coroutines be added? #144

vi opened this issue Sep 17, 2017 · 7 comments

Comments

@vi
Copy link
Member

vi commented Sep 17, 2017

I've created a port of "async-autobahn-server.rs" (sans error handling) using the futures-await / experimental coroutines.

#![feature(proc_macro, conservative_impl_trait, generators)]

extern crate websocket;
//extern crate futures;
extern crate futures_await as futures;
extern crate tokio_core;

use futures::prelude::*;

use websocket::message::OwnedMessage;
use websocket::async::Server;

use tokio_core::reactor::Core;
use futures::{Future, Sink, Stream};

type UsualClient = websocket::client::async::Framed<tokio_core::net::TcpStream, websocket::async::MessageCodec<websocket::OwnedMessage>>;

#[async]
fn serve_client(client: UsualClient) -> std::result::Result<(),()> {
    let (mut sink, stream) = client.split();
    #[async]
    for m in stream.map_err(|_|()) {
        if m.is_close() { break; }
        let fwd = match m {
            OwnedMessage::Ping(p) => OwnedMessage::Pong(p),
            OwnedMessage::Pong(_) => continue,
            _ => m,
        };
        sink = await!(sink.send(fwd).map_err(|_|()))?;
    }
    await!(sink.send(OwnedMessage::Close(None)).map_err(|_|()))?;
    Ok(())
}

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let server = Server::bind("127.0.0.1:9002", &handle).unwrap();

    let str = server.incoming().map_err(|_|());
	
    let f = async_block! {
        #[async]
        for (upgrade, addr) in str {
            // accept the request to be a ws connection
            println!("Got a connection from: {}", addr);
            let (client, _headers) = await!(upgrade.accept().map_err(|_|()))?;
            let f = serve_client(client);
            handle.spawn(f.map_err(|_|()).map(|_|()));
        }
        Ok::<(),()>(())
    };

    core.run(f).unwrap();
}

Should it be added to the examples or better to wait for stabilization of respective Rust features?

@marcelbuesing
Copy link

I think this looks great! You should probably create a pull request for it.

@vi
Copy link
Member Author

vi commented Nov 15, 2017

How do I avoid annoying non-nightly users with a fails-to-build example then?

Also futures_await crate isn't even on crates.io. Looks like it already is.

@vi
Copy link
Member Author

vi commented Nov 15, 2017

Note: published app based on this example to crates.io: wsbroad. Was previously only on Github. It also shows communication between connected clients.

@marcelbuesing
Copy link

Not sure what to say about the fails-to-build example, I guess the compiler message will make it obvious why the example fails to build with stable. I personally would not worry about that.

@vi
Copy link
Member Author

vi commented Nov 15, 2017

But as far as I know cargo test also tries building all examples. Breaking cargo test on non-nightly is a bad idea.

@marcelbuesing
Copy link

Ah I was not aware of that. Seems your right, I just tested it. Maybe create an examples-nightly folder that is not picked up by cargo test.

@illegalprime
Copy link
Collaborator

@vi awesome stuff, merge it into some other folder until we figure out what to do with the build step.

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