-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
845 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
[package] | ||
name = "routerify-websocket" | ||
version = "0.1.0" | ||
description = "An websocket extension for Routerify." | ||
version = "1.0.0" | ||
description = "The websocket support for the Routerify library." | ||
homepage = "https://github.com/routerify/routerify-websocket" | ||
repository = "https://github.com/routerify/routerify-websocket" | ||
keywords = ["routerify", "hyper-rs", "hyper", "websocket", "ws"] | ||
categories = ["asynchronous","web-programming","web-programming::http-server"] | ||
categories = ["asynchronous", "web-programming", "web-programming::websocket"] | ||
authors = ["Rousan Ali <[email protected]>"] | ||
readme = "README.md" | ||
license = "MIT" | ||
|
@@ -19,17 +19,24 @@ features = ["all"] | |
|
||
[features] | ||
default = [] | ||
all = [] | ||
all = ["json"] | ||
json = ["serde", "serde_json"] | ||
|
||
[dependencies] | ||
log = "0.4" | ||
derive_more = "0.99" | ||
routerify = "1.1" | ||
hyper = "0.13" | ||
tokio-tungstenite = { version = "0.10", default-features = false, optional = true } | ||
headers = { version = "0.3", optional = true } | ||
futures = { version = "0.3", default-features = false, optional = true } | ||
tokio = { version = "0.2", features = ["rt-core"], optional = true} | ||
headers = "0.3" | ||
tokio-tungstenite = { version = "0.10", default-features = false } | ||
futures = { version = "0.3", default-features = false } | ||
tokio = { version = "0.2", features = ["rt-core"] } | ||
|
||
serde = { version = "1.0", optional = true } | ||
serde_json = { version = "1.0", optional = true } | ||
|
||
[dev-dependencies] | ||
tokio = { version = "0.2", features = ["full"] } | ||
tokio = { version = "0.2", features = ["full"] } | ||
stream-body = "0.1" | ||
serde = { version = "1.0", features = ["derive"] } | ||
tokio-tungstenite = { version = "0.10", features = ["tls"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Import `SinkExt` and `StreamExt` to send and read websocket messages. | ||
use futures::{SinkExt, StreamExt}; | ||
use hyper::{Body, Response, Server}; | ||
use routerify::{Router, RouterService}; | ||
// Import websocket types. | ||
use routerify_websocket::{upgrade_ws, Message, WebSocket}; | ||
use std::{convert::Infallible, net::SocketAddr}; | ||
|
||
// A handler for websocket connections. | ||
async fn ws_handler(ws: WebSocket) { | ||
println!("New websocket connection: {}", ws.remote_addr()); | ||
|
||
// The `WebSocket` implements the `Sink` and `Stream` traits to read and write messages. | ||
let (mut tx, mut rx) = ws.split(); | ||
|
||
// Read messages. | ||
while let Some(msg) = rx.next().await { | ||
let msg = msg.unwrap(); | ||
|
||
// Check message type and take appropriate actions. | ||
if msg.is_text() { | ||
println!("{}", msg.into_text().unwrap()); | ||
} else if msg.is_binary() { | ||
println!("{:?}", msg.into_bytes()); | ||
} | ||
|
||
// Send a text message. | ||
let send_msg = Message::text("Hello world"); | ||
tx.send(send_msg).await.unwrap(); | ||
} | ||
} | ||
|
||
fn router() -> Router<Body, Infallible> { | ||
// Create a router and specify the path and the handler for new websocket connections. | ||
Router::builder() | ||
// It will accept websocket connections at `/ws` path with any method type. | ||
.any_method("/ws", upgrade_ws(ws_handler)) | ||
// It will accept http connections at `/` path. | ||
.get("/", |_req| async move { | ||
Ok(Response::new("I also serve http requests".into())) | ||
}) | ||
.build() | ||
.unwrap() | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let router = router(); | ||
|
||
// Create a Service from the router above to handle incoming requests. | ||
let service = RouterService::new(router).unwrap(); | ||
|
||
// The address on which the server will be listening. | ||
let addr = SocketAddr::from(([127, 0, 0, 1], 3001)); | ||
|
||
// Create a server by passing the created service to `.serve` method. | ||
let server = Server::bind(&addr).serve(service); | ||
|
||
println!("App is running on: {}", addr); | ||
if let Err(err) = server.await { | ||
eprintln!("Server error: {}", err); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use futures::{Sink, SinkExt, StreamExt}; | ||
use hyper::{Request, Response, Server}; | ||
use routerify::{Router, RouterService}; | ||
use routerify_websocket::{upgrade_ws, WebSocket}; | ||
use std::{convert::Infallible, net::SocketAddr}; | ||
use stream_body::StreamBody; | ||
use tokio::prelude::*; | ||
|
||
async fn ws_handler(ws: WebSocket) { | ||
println!("new websocket connection: {}", ws.remote_addr()); | ||
|
||
let (mut tx, mut rx) = ws.split(); | ||
|
||
while let Some(msg) = rx.next().await { | ||
let msg = msg.unwrap(); | ||
|
||
println!("{:?}", msg.close_reason()); | ||
println!("{}", String::from_utf8(msg.into_bytes()).unwrap()); | ||
} | ||
} | ||
|
||
fn router() -> Router<StreamBody, Infallible> { | ||
Router::builder() | ||
.any_method("/ws", upgrade_ws(ws_handler)) | ||
// Add options handler. | ||
.options( | ||
"/*", | ||
|_req| async move { Ok(Response::new(StreamBody::from("Options"))) }, | ||
) | ||
// Add 404 page handler. | ||
.any(|_req| async move { Ok(Response::new(StreamBody::from("Not Found"))) }) | ||
// Add an error handler. | ||
.err_handler(|err| async move { Response::new(StreamBody::from(format!("Error: {}", err))) }) | ||
.build() | ||
.unwrap() | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let router = router(); | ||
|
||
// Create a Service from the router above to handle incoming requests. | ||
let service = RouterService::new(router).unwrap(); | ||
|
||
// The address on which the server will be listening. | ||
let addr = SocketAddr::from(([127, 0, 0, 1], 3001)); | ||
|
||
// Create a server by passing the created service to `.serve` method. | ||
let server = Server::bind(&addr).serve(service); | ||
|
||
println!("App is running on: {}", addr); | ||
if let Err(err) = server.await { | ||
eprintln!("Server error: {}", err); | ||
} | ||
} |
Oops, something went wrong.