1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-06-25 18:09:22 +02:00

move examples/websocket.rs to examples/websocket

This commit is contained in:
ami44
2017-12-30 21:47:39 +01:00
parent e18f9f3f3a
commit 7962d28a6d
5 changed files with 50 additions and 4 deletions

View File

@ -0,0 +1,14 @@
[package]
name = "websocket"
version = "0.1.0"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
[[bin]]
name = "server"
path = "src/main.rs"
[dependencies]
env_logger = "*"
futures = "0.1"
actix = "^0.3.5"
actix-web = { git = "https://github.com/actix/actix-web.git", features=["signal"] }

View File

@ -0,0 +1,27 @@
# websockect
Simple echo websocket server.
## Usage
### server
```bash
cd actix-web/examples/websocket
cargo run
# Started http server: 127.0.0.1:8080
```
### web client
- [http://localhost:8080/ws/index.html](http://localhost:8080/ws/index.html)
### python client
- ``pip install aiohttp``
- ``python websocket-client.py``
if ubuntu :
- ``pip3 install aiohttp``
- ``python3 websocket-client.py``

View File

@ -0,0 +1,83 @@
//! Simple echo websocket server.
//! Open `http://localhost:8080/ws/index.html` in browser
//! or [python console client](https://github.com/actix/actix-web/blob/master/examples/websocket-client.py)
//! could be used for testing.
#![allow(unused_variables)]
extern crate actix;
extern crate actix_web;
extern crate env_logger;
use actix::*;
use actix_web::*;
#[cfg(target_os = "linux")] use actix::actors::signal::{ProcessSignals, Subscribe};
/// do websocket handshake and start `MyWebSocket` actor
fn ws_index(r: HttpRequest) -> Reply {
ws::start(r, MyWebSocket).into()
}
/// websocket connection is long running connection, it easier
/// to handle with an actor
struct MyWebSocket;
impl Actor for MyWebSocket {
type Context = HttpContext<Self>;
}
/// Standard actix's stream handler for a stream of `ws::Message`
impl StreamHandler<ws::Message> for MyWebSocket {
fn started(&mut self, ctx: &mut Self::Context) {
println!("WebSocket session openned");
}
fn finished(&mut self, ctx: &mut Self::Context) {
println!("WebSocket session closed");
}
}
impl Handler<ws::Message> for MyWebSocket {
fn handle(&mut self, msg: ws::Message, ctx: &mut HttpContext<Self>)
-> Response<Self, ws::Message>
{
// process websocket messages
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() {
::std::env::set_var("RUST_LOG", "actix_web=trace");
let _ = env_logger::init();
let sys = actix::System::new("ws-example");
let _addr = HttpServer::new(
|| Application::new()
// enable logger
.middleware(middleware::Logger::default())
// websocket route
.resource("/ws/", |r| r.method(Method::GET).f(ws_index))
// static files
.resource("/{tail:.*}",
|r| r.h(fs::StaticFiles::new("tail", "../static/", true))))
// start http server on 127.0.0.1:8080
.bind("127.0.0.1:8080").unwrap()
.start();
if cfg!(target_os = "linux") { // Subscribe to unix signals
let signals = Arbiter::system_registry().get::<ProcessSignals>();
signals.send(Subscribe(_addr.subscriber()));
}
println!("Started http server: 127.0.0.1:8080");
let _ = sys.run();
}

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""websocket cmd client for wssrv.py example."""
import argparse
import asyncio
import signal
import sys
import aiohttp
def start_client(loop, url):
name = input('Please enter your name: ')
# send request
ws = yield from aiohttp.ClientSession().ws_connect(url, autoclose=False, autoping=False)
# input reader
def stdin_callback():
line = sys.stdin.buffer.readline().decode('utf-8')
if not line:
loop.stop()
else:
ws.send_str(name + ': ' + line)
loop.add_reader(sys.stdin.fileno(), stdin_callback)
@asyncio.coroutine
def dispatch():
while True:
msg = yield from ws.receive()
if msg.type == aiohttp.WSMsgType.TEXT:
print('Text: ', msg.data.strip())
elif msg.type == aiohttp.WSMsgType.BINARY:
print('Binary: ', msg.data)
elif msg.type == aiohttp.WSMsgType.PING:
ws.pong()
elif msg.type == aiohttp.WSMsgType.PONG:
print('Pong received')
else:
if msg.type == aiohttp.WSMsgType.CLOSE:
yield from ws.close()
elif msg.type == aiohttp.WSMsgType.ERROR:
print('Error during receive %s' % ws.exception())
elif msg.type == aiohttp.WSMsgType.CLOSED:
pass
break
yield from dispatch()
ARGS = argparse.ArgumentParser(
description="websocket console client for wssrv.py example.")
ARGS.add_argument(
'--host', action="store", dest='host',
default='127.0.0.1', help='Host name')
ARGS.add_argument(
'--port', action="store", dest='port',
default=8080, type=int, help='Port number')
if __name__ == '__main__':
args = ARGS.parse_args()
if ':' in args.host:
args.host, port = args.host.split(':', 1)
args.port = int(port)
url = 'http://{}:{}/ws/'.format(args.host, args.port)
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, loop.stop)
asyncio.Task(start_client(loop, url))
loop.run_forever()