@@ -156,6 +156,47 @@ impl<S> Server<S>
156156 ssl_acceptor : self . ssl_acceptor . clone ( ) ,
157157 } )
158158 }
159+
160+ /// Changes whether the Server is in nonblocking mode.
161+ ///
162+ /// If it is in nonblocking mode, accept() will return an error instead of blocking when there
163+ /// are no incoming connections.
164+ ///
165+ ///# Examples
166+ ///```no_run
167+ /// # extern crate websocket;
168+ /// # use websocket::Server;
169+ /// # fn main() {
170+ /// // Suppose we have to work in a single thread, but want to
171+ /// // accomplish two unrelated things:
172+ /// // (1) Once in a while we want to check if anybody tried to connect to
173+ /// // our websocket server, and if so, handle the TcpStream.
174+ /// // (2) In between we need to something else, possibly unrelated to networking.
175+ ///
176+ /// let mut server = Server::bind("127.0.0.1:0").unwrap();
177+ ///
178+ /// // Set the server to non-blocking.
179+ /// server.set_nonblocking(true);
180+ ///
181+ /// for i in 1..3 {
182+ /// let result = match server.accept() {
183+ /// Ok(wsupgrade) => {
184+ /// // Do something with the established TcpStream.
185+ /// }
186+ /// _ => {
187+ /// // Nobody tried to connect, move on.
188+ /// }
189+ /// };
190+ /// // Perform another task. Because we have a non-blocking server,
191+ /// // this will execute independent of whether someone tried to
192+ /// // establish a connection.
193+ /// let two = 1+1;
194+ /// }
195+ /// # }
196+ ///```
197+ pub fn set_nonblocking ( & self , nonblocking : bool ) -> io:: Result < ( ) > {
198+ self . listener . set_nonblocking ( nonblocking)
199+ }
159200}
160201
161202#[ cfg( feature="ssl" ) ]
@@ -208,14 +249,6 @@ impl Server<SslAcceptor> {
208249 }
209250 }
210251 }
211-
212- /// Changes whether the Server is in nonblocking mode.
213- ///
214- /// If it is in nonblocking mode, accept() will return an error instead of blocking when there
215- /// are no incoming connections.
216- pub fn set_nonblocking ( & self , nonblocking : bool ) -> io:: Result < ( ) > {
217- self . listener . set_nonblocking ( nonblocking)
218- }
219252}
220253
221254#[ cfg( feature="ssl" ) ]
@@ -271,3 +304,36 @@ impl Iterator for Server<NoSslAcceptor> {
271304 Some ( self . accept ( ) )
272305 }
273306}
307+
308+ mod tests {
309+ #[ test]
310+ // test the set_nonblocking() method for Server<NoSslAcceptor>.
311+ // Some of this is copied from
312+ // https://doc.rust-lang.org/src/std/net/tcp.rs.html#1413
313+ fn set_nonblocking ( ) {
314+
315+ use super :: * ;
316+
317+ // Test unsecure server
318+
319+ let mut server = Server :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
320+
321+ // Note that if set_nonblocking() doesn't work, but the following
322+ // fails to panic for some reason, then the .accept() method below
323+ // will block indefinitely.
324+ server. set_nonblocking ( true ) . unwrap ( ) ;
325+
326+ let result = server. accept ( ) ;
327+ match result {
328+ // nobody tried to establish a connection, so we expect an error
329+ Ok ( _) => panic ! ( "expected error" ) ,
330+ Err ( e) => {
331+ match e. error {
332+ HyperIntoWsError :: Io ( ref e) if e. kind ( ) == io:: ErrorKind :: WouldBlock => { }
333+ _ => panic ! ( "unexpected error {}" ) ,
334+ }
335+ }
336+ }
337+
338+ }
339+ }
0 commit comments