mirror of
https://github.com/actix/examples
synced 2024-11-23 22:41:07 +01:00
fix missing heartbeat
This commit is contained in:
parent
13834d8076
commit
58d3e5f8c5
@ -21,6 +21,7 @@ use std::time::Instant;
|
|||||||
use actix::*;
|
use actix::*;
|
||||||
use actix_web::server::HttpServer;
|
use actix_web::server::HttpServer;
|
||||||
use actix_web::{fs, http, ws, App, Error, HttpRequest, HttpResponse};
|
use actix_web::{fs, http, ws, App, Error, HttpRequest, HttpResponse};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
mod codec;
|
mod codec;
|
||||||
mod server;
|
mod server;
|
||||||
@ -68,6 +69,10 @@ impl Actor for WsChatSession {
|
|||||||
// before processing any other events.
|
// before processing any other events.
|
||||||
// HttpContext::state() is instance of WsChatSessionState, state is shared
|
// HttpContext::state() is instance of WsChatSessionState, state is shared
|
||||||
// across all routes within application
|
// across all routes within application
|
||||||
|
|
||||||
|
// we'll start heartbeat process on session start.
|
||||||
|
self.hb(ctx);
|
||||||
|
|
||||||
let addr = ctx.address();
|
let addr = ctx.address();
|
||||||
ctx.state()
|
ctx.state()
|
||||||
.addr
|
.addr
|
||||||
@ -183,6 +188,34 @@ impl StreamHandler<ws::Message, ws::ProtocolError> for WsChatSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WsChatSession {
|
||||||
|
/// helper method that sends ping to client every second.
|
||||||
|
///
|
||||||
|
/// also this method check heartbeats from client
|
||||||
|
fn hb(&self, ctx: &mut ws::WebsocketContext<Self, WsChatSessionState>) {
|
||||||
|
ctx.run_later(Duration::new(1, 0), |act, ctx| {
|
||||||
|
// check client heartbeats
|
||||||
|
if Instant::now().duration_since(act.hb) > Duration::new(10, 0) {
|
||||||
|
// heartbeat timed out
|
||||||
|
println!("Websocket Client heartbeat failed, disconnecting!");
|
||||||
|
|
||||||
|
// notify chat server
|
||||||
|
ctx.state()
|
||||||
|
.addr
|
||||||
|
.do_send(server::Disconnect { id: act.id });
|
||||||
|
|
||||||
|
// stop actor
|
||||||
|
ctx.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.ping("");
|
||||||
|
|
||||||
|
// if we can not send message to sink, sink is closed (disconnected)
|
||||||
|
act.hb(ctx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = env_logger::init();
|
let _ = env_logger::init();
|
||||||
let sys = actix::System::new("websocket-example");
|
let sys = actix::System::new("websocket-example");
|
||||||
@ -205,15 +238,15 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
App::with_state(state)
|
App::with_state(state)
|
||||||
// redirect to websocket.html
|
// redirect to websocket.html
|
||||||
.resource("/", |r| r.method(http::Method::GET).f(|_| {
|
.resource("/", |r| r.method(http::Method::GET).f(|_| {
|
||||||
HttpResponse::Found()
|
HttpResponse::Found()
|
||||||
.header("LOCATION", "/static/websocket.html")
|
.header("LOCATION", "/static/websocket.html")
|
||||||
.finish()
|
.finish()
|
||||||
}))
|
}))
|
||||||
// websocket
|
// websocket
|
||||||
.resource("/ws/", |r| r.route().f(chat_route))
|
.resource("/ws/", |r| r.route().f(chat_route))
|
||||||
// static resources
|
// static resources
|
||||||
.handler("/static/", fs::StaticFiles::new("static/").unwrap())
|
.handler("/static/", fs::StaticFiles::new("static/").unwrap())
|
||||||
}).bind("127.0.0.1:8080")
|
}).bind("127.0.0.1:8080")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
Loading…
Reference in New Issue
Block a user