1 extern crate env_logger;
2 /// WebSocket server using trait objects to route
3 /// to an infinitely extensible number of handlers
4 extern crate ws;
5 
6 // A WebSocket handler that routes connections to different boxed handlers by resource
7 struct Router {
8     sender: ws::Sender,
9     inner: Box<ws::Handler>,
10 }
11 
12 impl ws::Handler for Router {
on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)>13     fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
14         // Clone the sender so that we can move it into the child handler
15         let out = self.sender.clone();
16 
17         match req.resource() {
18             "/echo" => self.inner = Box::new(Echo { ws: out }),
19 
20             // Route to a data handler
21             "/data/one" => {
22                 self.inner = Box::new(Data {
23                     ws: out,
24                     data: vec!["one", "two", "three", "four", "five"],
25                 })
26             }
27 
28             // Route to another data handler
29             "/data/two" => {
30                 self.inner = Box::new(Data {
31                     ws: out,
32                     data: vec!["いち", "二", "さん", "四", "ご"],
33                 })
34             }
35 
36             // Use a closure as the child handler
37             "/closure" => {
38                 self.inner = Box::new(move |msg: ws::Message| {
39                     println!("Got a message on a closure handler: {}", msg);
40                     out.close_with_reason(ws::CloseCode::Error, "Not Implemented.")
41                 })
42             }
43 
44             // Use the default child handler, NotFound
45             _ => (),
46         }
47 
48         // Delegate to the child handler
49         self.inner.on_request(req)
50     }
51 
52     // Pass through any other methods that should be delegated to the child.
53     //
54     // You could probably use a macro for this if you have many different
55     // routers or were building some sort of routing framework.
56 
on_shutdown(&mut self)57     fn on_shutdown(&mut self) {
58         self.inner.on_shutdown()
59     }
60 
on_open(&mut self, shake: ws::Handshake) -> ws::Result<()>61     fn on_open(&mut self, shake: ws::Handshake) -> ws::Result<()> {
62         self.inner.on_open(shake)
63     }
64 
on_message(&mut self, msg: ws::Message) -> ws::Result<()>65     fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
66         self.inner.on_message(msg)
67     }
68 
on_close(&mut self, code: ws::CloseCode, reason: &str)69     fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
70         self.inner.on_close(code, reason)
71     }
72 
on_error(&mut self, err: ws::Error)73     fn on_error(&mut self, err: ws::Error) {
74         self.inner.on_error(err);
75     }
76 }
77 
78 // This handler returns a 404 response to all handshake requests
79 struct NotFound;
80 
81 impl ws::Handler for NotFound {
on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)>82     fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
83         // This handler responds to all requests with a 404
84         let mut res = ws::Response::from_request(req)?;
85         res.set_status(404);
86         res.set_reason("Not Found");
87         Ok(res)
88     }
89 }
90 
91 // This handler simply echoes all messages back to the client
92 struct Echo {
93     ws: ws::Sender,
94 }
95 
96 impl ws::Handler for Echo {
on_message(&mut self, msg: ws::Message) -> ws::Result<()>97     fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
98         println!("Echo handler received a message: {}", msg);
99         self.ws.send(msg)
100     }
101 }
102 
103 // This handler sends some data to the client and then terminates the connection on the first
104 // message received, presumably confirming receipt of the data
105 struct Data {
106     ws: ws::Sender,
107     data: Vec<&'static str>,
108 }
109 
110 impl ws::Handler for Data {
on_open(&mut self, _: ws::Handshake) -> ws::Result<()>111     fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
112         for msg in &self.data {
113             self.ws.send(*msg)?
114         }
115         Ok(())
116     }
117 
on_message(&mut self, msg: ws::Message) -> ws::Result<()>118     fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
119         println!("Data handler received a message: {}", msg);
120         println!("Data handler going down.");
121         self.ws.close(ws::CloseCode::Normal)
122     }
123 }
124 
main()125 fn main() {
126     env_logger::init();
127 
128     // Listen on an address and call the closure for each connection
129     if let Err(error) = ws::listen("127.0.0.1:3012", |out| {
130         // Use our router as the handler to route the new connection
131         Router {
132             sender: out,
133             // Default to returning a 404 when the route doesn't match.
134             // You could default to any handler here.
135             inner: Box::new(NotFound),
136         }
137     }) {
138         // Inform the user of failure
139         println!("Failed to create WebSocket due to {:?}", error);
140     }
141 }
142