//! Simple websocket client. use std::time::Duration; use std::{io, thread}; use actix::io::SinkWrite; use actix::*; use actix_codec::Framed; use awc::{ error::WsProtocolError, ws::{Codec, Frame, Message}, BoxedSocket, Client, }; use bytes::Bytes; use futures::stream::{SplitSink, StreamExt}; fn main() { ::std::env::set_var("RUST_LOG", "actix_web=info"); env_logger::init(); let sys = System::new("websocket-client"); Arbiter::spawn(async { let (response, framed) = Client::new() .ws("http://127.0.0.1:8080/ws/") .connect() .await .map_err(|e| { println!("Error: {}", e); }) .unwrap(); println!("{:?}", response); let (sink, stream) = framed.split(); let addr = ChatClient::create(|ctx| { ChatClient::add_stream(stream, ctx); ChatClient(SinkWrite::new(sink, ctx)) }); // start console loop thread::spawn(move || loop { let mut cmd = String::new(); if io::stdin().read_line(&mut cmd).is_err() { println!("error"); return; } addr.do_send(ClientCommand(cmd)); }); }); sys.run().unwrap(); } struct ChatClient(SinkWrite, Message>>); #[derive(Message)] #[rtype(result = "()")] struct ClientCommand(String); impl Actor for ChatClient { type Context = Context; fn started(&mut self, ctx: &mut Context) { // start heartbeats otherwise server will disconnect after 10 seconds self.hb(ctx) } fn stopped(&mut self, _: &mut Context) { println!("Disconnected"); // Stop application on disconnect System::current().stop(); } } impl ChatClient { fn hb(&self, ctx: &mut Context) { ctx.run_later(Duration::new(1, 0), |act, ctx| { act.0.write(Message::Ping(Bytes::from_static(b""))); act.hb(ctx); // client should also check for a timeout here, similar to the // server code }); } } /// Handle stdin commands impl Handler for ChatClient { type Result = (); fn handle(&mut self, msg: ClientCommand, _ctx: &mut Context) { self.0.write(Message::Text(msg.0)); } } /// Handle server websocket messages impl StreamHandler> for ChatClient { fn handle(&mut self, msg: Result, _: &mut Context) { if let Ok(Frame::Text(txt)) = msg { println!("Server: {:?}", txt) } } fn started(&mut self, _ctx: &mut Context) { println!("Connected"); } fn finished(&mut self, ctx: &mut Context) { println!("Server disconnected"); ctx.stop() } } impl actix::io::WriteHandler for ChatClient {}