summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ws/examples/router.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/ws/examples/router.rs')
-rw-r--r--third_party/rust/ws/examples/router.rs141
1 files changed, 141 insertions, 0 deletions
diff --git a/third_party/rust/ws/examples/router.rs b/third_party/rust/ws/examples/router.rs
new file mode 100644
index 0000000000..8e699298e9
--- /dev/null
+++ b/third_party/rust/ws/examples/router.rs
@@ -0,0 +1,141 @@
+extern crate env_logger;
+/// WebSocket server using trait objects to route
+/// to an infinitely extensible number of handlers
+extern crate ws;
+
+// A WebSocket handler that routes connections to different boxed handlers by resource
+struct Router {
+ sender: ws::Sender,
+ inner: Box<ws::Handler>,
+}
+
+impl ws::Handler for Router {
+ fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
+ // Clone the sender so that we can move it into the child handler
+ let out = self.sender.clone();
+
+ match req.resource() {
+ "/echo" => self.inner = Box::new(Echo { ws: out }),
+
+ // Route to a data handler
+ "/data/one" => {
+ self.inner = Box::new(Data {
+ ws: out,
+ data: vec!["one", "two", "three", "four", "five"],
+ })
+ }
+
+ // Route to another data handler
+ "/data/two" => {
+ self.inner = Box::new(Data {
+ ws: out,
+ data: vec!["いち", "二", "さん", "四", "ご"],
+ })
+ }
+
+ // Use a closure as the child handler
+ "/closure" => {
+ self.inner = Box::new(move |msg: ws::Message| {
+ println!("Got a message on a closure handler: {}", msg);
+ out.close_with_reason(ws::CloseCode::Error, "Not Implemented.")
+ })
+ }
+
+ // Use the default child handler, NotFound
+ _ => (),
+ }
+
+ // Delegate to the child handler
+ self.inner.on_request(req)
+ }
+
+ // Pass through any other methods that should be delegated to the child.
+ //
+ // You could probably use a macro for this if you have many different
+ // routers or were building some sort of routing framework.
+
+ fn on_shutdown(&mut self) {
+ self.inner.on_shutdown()
+ }
+
+ fn on_open(&mut self, shake: ws::Handshake) -> ws::Result<()> {
+ self.inner.on_open(shake)
+ }
+
+ fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
+ self.inner.on_message(msg)
+ }
+
+ fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
+ self.inner.on_close(code, reason)
+ }
+
+ fn on_error(&mut self, err: ws::Error) {
+ self.inner.on_error(err);
+ }
+}
+
+// This handler returns a 404 response to all handshake requests
+struct NotFound;
+
+impl ws::Handler for NotFound {
+ fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
+ // This handler responds to all requests with a 404
+ let mut res = ws::Response::from_request(req)?;
+ res.set_status(404);
+ res.set_reason("Not Found");
+ Ok(res)
+ }
+}
+
+// This handler simply echoes all messages back to the client
+struct Echo {
+ ws: ws::Sender,
+}
+
+impl ws::Handler for Echo {
+ fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
+ println!("Echo handler received a message: {}", msg);
+ self.ws.send(msg)
+ }
+}
+
+// This handler sends some data to the client and then terminates the connection on the first
+// message received, presumably confirming receipt of the data
+struct Data {
+ ws: ws::Sender,
+ data: Vec<&'static str>,
+}
+
+impl ws::Handler for Data {
+ fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
+ for msg in &self.data {
+ self.ws.send(*msg)?
+ }
+ Ok(())
+ }
+
+ fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
+ println!("Data handler received a message: {}", msg);
+ println!("Data handler going down.");
+ self.ws.close(ws::CloseCode::Normal)
+ }
+}
+
+fn main() {
+ env_logger::init();
+
+ // Listen on an address and call the closure for each connection
+ if let Err(error) = ws::listen("127.0.0.1:3012", |out| {
+ // Use our router as the handler to route the new connection
+ Router {
+ sender: out,
+ // Default to returning a 404 when the route doesn't match.
+ // You could default to any handler here.
+ inner: Box::new(NotFound),
+ }
+ }) {
+ // Inform the user of failure
+ println!("Failed to create WebSocket due to {:?}", error);
+ }
+}