mirror of
https://github.com/actix/actix-web.git
synced 2024-11-25 11:01:14 +00:00
add simple websocket example
This commit is contained in:
parent
9fd84a0aef
commit
71dc9edf8e
7 changed files with 181 additions and 36 deletions
|
@ -1,32 +0,0 @@
|
|||
import asyncio
|
||||
import aiohttp
|
||||
|
||||
|
||||
def req1():
|
||||
with aiohttp.MultipartWriter() as writer:
|
||||
writer.append('test')
|
||||
writer.append_json({'passed': True})
|
||||
|
||||
resp = yield from aiohttp.request(
|
||||
"post", 'http://localhost:8080/multipart',
|
||||
data=writer, headers=writer.headers)
|
||||
print(resp)
|
||||
assert 200 == resp.status
|
||||
|
||||
|
||||
def req2():
|
||||
with aiohttp.MultipartWriter() as writer:
|
||||
writer.append('test')
|
||||
writer.append_json({'passed': True})
|
||||
writer.append(open('src/main.rs'))
|
||||
|
||||
resp = yield from aiohttp.request(
|
||||
"post", 'http://localhost:8080/multipart',
|
||||
data=writer, headers=writer.headers)
|
||||
print(resp)
|
||||
assert 200 == resp.status
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(req1())
|
||||
loop.run_until_complete(req2())
|
12
examples/websocket/Cargo.toml
Normal file
12
examples/websocket/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "websocket-example"
|
||||
version = "0.1.0"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
|
||||
[[bin]]
|
||||
name = "websocket"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
actix = { git = "https://github.com/fafhrd91/actix.git" }
|
||||
actix-web = { path = "../../" }
|
73
examples/websocket/src/main.rs
Normal file
73
examples/websocket/src/main.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
#![allow(unused_variables)]
|
||||
extern crate actix;
|
||||
extern crate actix_web;
|
||||
|
||||
use actix::*;
|
||||
use actix_web::*;
|
||||
|
||||
|
||||
struct MyWebSocket;
|
||||
|
||||
impl Actor for MyWebSocket {
|
||||
type Context = HttpContext<Self>;
|
||||
}
|
||||
|
||||
impl Route for MyWebSocket {
|
||||
type State = ();
|
||||
|
||||
fn request(req: HttpRequest, payload: Payload, ctx: &mut HttpContext<Self>) -> Reply<Self>
|
||||
{
|
||||
match ws::handshake(&req) {
|
||||
Ok(resp) => {
|
||||
ctx.start(resp);
|
||||
ctx.add_stream(ws::WsStream::new(payload));
|
||||
Reply::async(MyWebSocket)
|
||||
}
|
||||
Err(err) => {
|
||||
Reply::reply(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseType<ws::Message> for MyWebSocket {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
impl StreamHandler<ws::Message> for MyWebSocket {}
|
||||
|
||||
impl Handler<ws::Message> for MyWebSocket {
|
||||
fn handle(&mut self, msg: ws::Message, ctx: &mut HttpContext<Self>)
|
||||
-> Response<Self, ws::Message>
|
||||
{
|
||||
println!("WS: {:?}", msg);
|
||||
match msg {
|
||||
ws::Message::Ping(msg) => ws::WsWriter::pong(ctx, msg),
|
||||
ws::Message::Text(text) => ws::WsWriter::text(ctx, &text),
|
||||
ws::Message::Binary(bin) => ws::WsWriter::binary(ctx, bin),
|
||||
ws::Message::Closed | ws::Message::Error => {
|
||||
ctx.stop();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Self::empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let sys = actix::System::new("ws-example");
|
||||
|
||||
HttpServer::new(
|
||||
RoutingMap::default()
|
||||
.resource("/ws/", |r| r.get::<MyWebSocket>())
|
||||
.app("/", Application::default()
|
||||
.route_handler("/", StaticFiles::new("static/", true))
|
||||
.finish())
|
||||
.finish())
|
||||
.serve::<_, ()>("127.0.0.1:8080").unwrap();
|
||||
|
||||
println!("Started http server: 127.0.0.1:8080");
|
||||
let _ = sys.run();
|
||||
}
|
90
examples/websocket/static/index.html
Normal file
90
examples/websocket/static/index.html
Normal file
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
|
||||
</script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
$(function() {
|
||||
var conn = null;
|
||||
function log(msg) {
|
||||
var control = $('#log');
|
||||
control.html(control.html() + msg + '<br/>');
|
||||
control.scrollTop(control.scrollTop() + 1000);
|
||||
}
|
||||
function connect() {
|
||||
disconnect();
|
||||
var wsUri = (window.location.protocol=='https:'&&'wss://'||'ws://')+window.location.host + '/ws/';
|
||||
conn = new WebSocket(wsUri);
|
||||
log('Connecting...');
|
||||
conn.onopen = function() {
|
||||
log('Connected.');
|
||||
update_ui();
|
||||
};
|
||||
conn.onmessage = function(e) {
|
||||
log('Received: ' + e.data);
|
||||
};
|
||||
conn.onclose = function() {
|
||||
log('Disconnected.');
|
||||
conn = null;
|
||||
update_ui();
|
||||
};
|
||||
}
|
||||
function disconnect() {
|
||||
if (conn != null) {
|
||||
log('Disconnecting...');
|
||||
conn.close();
|
||||
conn = null;
|
||||
update_ui();
|
||||
}
|
||||
}
|
||||
function update_ui() {
|
||||
var msg = '';
|
||||
if (conn == null) {
|
||||
$('#status').text('disconnected');
|
||||
$('#connect').html('Connect');
|
||||
} else {
|
||||
$('#status').text('connected (' + conn.protocol + ')');
|
||||
$('#connect').html('Disconnect');
|
||||
}
|
||||
}
|
||||
$('#connect').click(function() {
|
||||
if (conn == null) {
|
||||
connect();
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
update_ui();
|
||||
return false;
|
||||
});
|
||||
$('#send').click(function() {
|
||||
var text = $('#text').val();
|
||||
log('Sending: ' + text);
|
||||
conn.send(text);
|
||||
$('#text').val('').focus();
|
||||
return false;
|
||||
});
|
||||
$('#text').keyup(function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
$('#send').click();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Chat!</h3>
|
||||
<div>
|
||||
<button id="connect">Connect</button> | Status:
|
||||
<span id="status">disconnected</span>
|
||||
</div>
|
||||
<div id="log"
|
||||
style="width:20em;height:15em;overflow:auto;border:1px solid black">
|
||||
</div>
|
||||
<form id="chatform" onsubmit="return false;">
|
||||
<input id="text" type="text" />
|
||||
<input id="send" type="button" value="Send" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -148,11 +148,11 @@ pub struct HttpChannel<T: 'static, A: 'static> {
|
|||
keepalive_timer: Option<Timeout>,
|
||||
}
|
||||
|
||||
impl<T: 'static, A: 'static> Drop for HttpChannel<T, A> {
|
||||
/*impl<T: 'static, A: 'static> Drop for HttpChannel<T, A> {
|
||||
fn drop(&mut self) {
|
||||
println!("Drop http channel");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
impl<T, A> Actor for HttpChannel<T, A>
|
||||
where T: AsyncRead + AsyncWrite + 'static, A: 'static
|
||||
|
|
|
@ -129,7 +129,9 @@ impl StaticFiles {
|
|||
impl<S: 'static> RouteHandler<S> for StaticFiles {
|
||||
|
||||
fn set_prefix(&mut self, prefix: String) {
|
||||
self.prefix += &prefix;
|
||||
if prefix != "/" {
|
||||
self.prefix += &prefix;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle(&self, req: HttpRequest, payload: Payload, state: Rc<S>) -> Task {
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
//! {
|
||||
//! match msg {
|
||||
//! ws::Message::Ping(msg) => ws::WsWriter::pong(ctx, msg),
|
||||
//! ws::Message::Text(text) => ws::WsWriter::text(ctx, text),
|
||||
//! ws::Message::Text(text) => ws::WsWriter::text(ctx, &text),
|
||||
//! ws::Message::Binary(bin) => ws::WsWriter::binary(ctx, bin),
|
||||
//! _ => (),
|
||||
//! }
|
||||
|
|
Loading…
Reference in a new issue