mirror of
https://github.com/fafhrd91/actix-web
synced 2024-12-18 09:53:11 +01:00
update websocket-chat example
This commit is contained in:
parent
f8f99ec0c7
commit
6181a84d7b
@ -13,6 +13,8 @@ use std::str::FromStr;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use tokio_io::AsyncRead;
|
use tokio_io::AsyncRead;
|
||||||
|
use tokio_io::io::WriteHalf;
|
||||||
|
use tokio_io::codec::FramedRead;
|
||||||
use tokio_core::net::TcpStream;
|
use tokio_core::net::TcpStream;
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
@ -27,12 +29,12 @@ fn main() {
|
|||||||
Arbiter::handle().spawn(
|
Arbiter::handle().spawn(
|
||||||
TcpStream::connect(&addr, Arbiter::handle())
|
TcpStream::connect(&addr, Arbiter::handle())
|
||||||
.and_then(|stream| {
|
.and_then(|stream| {
|
||||||
let addr: SyncAddress<_> = ChatClient::create(|mut ctx| {
|
let addr: SyncAddress<_> = ChatClient::create(|ctx| {
|
||||||
let (reader, writer) =
|
let (r, w) = stream.split();
|
||||||
FramedReader::wrap(stream.framed(codec::ClientChatCodec));
|
ChatClient::add_stream(FramedRead::new(r, codec::ClientChatCodec), ctx);
|
||||||
ChatClient::add_stream(reader, &mut ctx);
|
ChatClient{
|
||||||
ChatClient{framed: writer}
|
framed: actix::io::FramedWrite::new(
|
||||||
});
|
w, codec::ClientChatCodec, ctx)}});
|
||||||
|
|
||||||
// start console loop
|
// start console loop
|
||||||
thread::spawn(move|| {
|
thread::spawn(move|| {
|
||||||
@ -61,7 +63,7 @@ fn main() {
|
|||||||
|
|
||||||
|
|
||||||
struct ChatClient {
|
struct ChatClient {
|
||||||
framed: FramedWriter<TcpStream, codec::ClientChatCodec>,
|
framed: actix::io::FramedWrite<WriteHalf<TcpStream>, codec::ClientChatCodec>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
@ -88,12 +90,14 @@ impl Actor for ChatClient {
|
|||||||
impl ChatClient {
|
impl ChatClient {
|
||||||
fn hb(&self, ctx: &mut Context<Self>) {
|
fn hb(&self, ctx: &mut Context<Self>) {
|
||||||
ctx.run_later(Duration::new(1, 0), |act, ctx| {
|
ctx.run_later(Duration::new(1, 0), |act, ctx| {
|
||||||
act.framed.send(codec::ChatRequest::Ping);
|
act.framed.write(codec::ChatRequest::Ping);
|
||||||
act.hb(ctx);
|
act.hb(ctx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl actix::io::WriteHandler<io::Error> for ChatClient {}
|
||||||
|
|
||||||
/// Handle stdin commands
|
/// Handle stdin commands
|
||||||
impl Handler<ClientCommand> for ChatClient {
|
impl Handler<ClientCommand> for ChatClient {
|
||||||
type Result = ();
|
type Result = ();
|
||||||
@ -109,11 +113,11 @@ impl Handler<ClientCommand> for ChatClient {
|
|||||||
let v: Vec<&str> = m.splitn(2, ' ').collect();
|
let v: Vec<&str> = m.splitn(2, ' ').collect();
|
||||||
match v[0] {
|
match v[0] {
|
||||||
"/list" => {
|
"/list" => {
|
||||||
let _ = self.framed.send(codec::ChatRequest::List);
|
self.framed.write(codec::ChatRequest::List);
|
||||||
},
|
},
|
||||||
"/join" => {
|
"/join" => {
|
||||||
if v.len() == 2 {
|
if v.len() == 2 {
|
||||||
let _ = self.framed.send(codec::ChatRequest::Join(v[1].to_owned()));
|
self.framed.write(codec::ChatRequest::Join(v[1].to_owned()));
|
||||||
} else {
|
} else {
|
||||||
println!("!!! room name is required");
|
println!("!!! room name is required");
|
||||||
}
|
}
|
||||||
@ -121,14 +125,14 @@ impl Handler<ClientCommand> for ChatClient {
|
|||||||
_ => println!("!!! unknown command"),
|
_ => println!("!!! unknown command"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let _ = self.framed.send(codec::ChatRequest::Message(m.to_owned()));
|
self.framed.write(codec::ChatRequest::Message(m.to_owned()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Server communication
|
/// Server communication
|
||||||
|
|
||||||
impl StreamHandler<codec::ChatResponse, FramedError<codec::ClientChatCodec>> for ChatClient {
|
impl StreamHandler<codec::ChatResponse, io::Error> for ChatClient {
|
||||||
|
|
||||||
fn handle(&mut self, msg: codec::ChatResponse, _: &mut Context<Self>) {
|
fn handle(&mut self, msg: codec::ChatResponse, _: &mut Context<Self>) {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
//! `ClientSession` is an actor, it manages peer tcp connection and
|
//! `ClientSession` is an actor, it manages peer tcp connection and
|
||||||
//! proxies commands from peer to `ChatServer`.
|
//! proxies commands from peer to `ChatServer`.
|
||||||
use std::net;
|
use std::{io, net};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use tokio_io::AsyncRead;
|
use tokio_io::AsyncRead;
|
||||||
|
use tokio_io::io::WriteHalf;
|
||||||
|
use tokio_io::codec::FramedRead;
|
||||||
use tokio_core::net::{TcpStream, TcpListener};
|
use tokio_core::net::{TcpStream, TcpListener};
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
@ -28,7 +30,7 @@ pub struct ChatSession {
|
|||||||
/// joined room
|
/// joined room
|
||||||
room: String,
|
room: String,
|
||||||
/// Framed wrapper
|
/// Framed wrapper
|
||||||
framed: FramedWriter<TcpStream, ChatCodec>,
|
framed: actix::io::FramedWrite<WriteHalf<TcpStream>, ChatCodec>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for ChatSession {
|
impl Actor for ChatSession {
|
||||||
@ -62,8 +64,10 @@ impl Actor for ChatSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl actix::io::WriteHandler<io::Error> for ChatSession {}
|
||||||
|
|
||||||
/// To use `Framed` we have to define Io type and Codec
|
/// To use `Framed` we have to define Io type and Codec
|
||||||
impl StreamHandler<ChatRequest, FramedError<ChatCodec>> for ChatSession {
|
impl StreamHandler<ChatRequest, io::Error> for ChatSession {
|
||||||
|
|
||||||
/// This is main event loop for client requests
|
/// This is main event loop for client requests
|
||||||
fn handle(&mut self, msg: ChatRequest, ctx: &mut Context<Self>) {
|
fn handle(&mut self, msg: ChatRequest, ctx: &mut Context<Self>) {
|
||||||
@ -74,7 +78,7 @@ impl StreamHandler<ChatRequest, FramedError<ChatCodec>> for ChatSession {
|
|||||||
self.addr.call(self, server::ListRooms).then(|res, act, ctx| {
|
self.addr.call(self, server::ListRooms).then(|res, act, ctx| {
|
||||||
match res {
|
match res {
|
||||||
Ok(Ok(rooms)) => {
|
Ok(Ok(rooms)) => {
|
||||||
let _ = act.framed.send(ChatResponse::Rooms(rooms));
|
act.framed.write(ChatResponse::Rooms(rooms));
|
||||||
},
|
},
|
||||||
_ => println!("Something is wrong"),
|
_ => println!("Something is wrong"),
|
||||||
}
|
}
|
||||||
@ -87,7 +91,7 @@ impl StreamHandler<ChatRequest, FramedError<ChatCodec>> for ChatSession {
|
|||||||
println!("Join to room: {}", name);
|
println!("Join to room: {}", name);
|
||||||
self.room = name.clone();
|
self.room = name.clone();
|
||||||
self.addr.send(server::Join{id: self.id, name: name.clone()});
|
self.addr.send(server::Join{id: self.id, name: name.clone()});
|
||||||
let _ = self.framed.send(ChatResponse::Joined(name));
|
self.framed.write(ChatResponse::Joined(name));
|
||||||
},
|
},
|
||||||
ChatRequest::Message(message) => {
|
ChatRequest::Message(message) => {
|
||||||
// send message to chat server
|
// send message to chat server
|
||||||
@ -110,7 +114,7 @@ impl Handler<Message> for ChatSession {
|
|||||||
|
|
||||||
fn handle(&mut self, msg: Message, ctx: &mut Context<Self>) {
|
fn handle(&mut self, msg: Message, ctx: &mut Context<Self>) {
|
||||||
// send message to peer
|
// send message to peer
|
||||||
let _ = self.framed.send(ChatResponse::Message(msg.0));
|
self.framed.write(ChatResponse::Message(msg.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +122,7 @@ impl Handler<Message> for ChatSession {
|
|||||||
impl ChatSession {
|
impl ChatSession {
|
||||||
|
|
||||||
pub fn new(addr: SyncAddress<ChatServer>,
|
pub fn new(addr: SyncAddress<ChatServer>,
|
||||||
framed: FramedWriter<TcpStream, ChatCodec>) -> ChatSession {
|
framed: actix::io::FramedWrite<WriteHalf<TcpStream>, ChatCodec>) -> ChatSession {
|
||||||
ChatSession {id: 0, addr: addr, hb: Instant::now(),
|
ChatSession {id: 0, addr: addr, hb: Instant::now(),
|
||||||
room: "Main".to_owned(), framed: framed}
|
room: "Main".to_owned(), framed: framed}
|
||||||
}
|
}
|
||||||
@ -140,7 +144,7 @@ impl ChatSession {
|
|||||||
ctx.stop();
|
ctx.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
act.framed.send(ChatResponse::Ping);
|
act.framed.write(ChatResponse::Ping);
|
||||||
// if we can not send message to sink, sink is closed (disconnected)
|
// if we can not send message to sink, sink is closed (disconnected)
|
||||||
act.hb(ctx);
|
act.hb(ctx);
|
||||||
});
|
});
|
||||||
@ -191,10 +195,10 @@ impl Handler<TcpConnect> for TcpServer {
|
|||||||
// For each incoming connection we create `ChatSession` actor
|
// For each incoming connection we create `ChatSession` actor
|
||||||
// with out chat server address.
|
// with out chat server address.
|
||||||
let server = self.chat.clone();
|
let server = self.chat.clone();
|
||||||
let _: () = ChatSession::create(|mut ctx| {
|
let _: () = ChatSession::create(|ctx| {
|
||||||
let (reader, writer) = FramedReader::wrap(msg.0.framed(ChatCodec));
|
let (r, w) = msg.0.split();
|
||||||
ChatSession::add_stream(reader, &mut ctx);
|
ChatSession::add_stream(FramedRead::new(r, ChatCodec), ctx);
|
||||||
ChatSession::new(server, writer)
|
ChatSession::new(server, actix::io::FramedWrite::new(w, ChatCodec, ctx))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user