@@ -156,6 +156,47 @@ impl<S> Server<S>
156
156
ssl_acceptor : self . ssl_acceptor . clone ( ) ,
157
157
} )
158
158
}
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
+ }
159
200
}
160
201
161
202
#[ cfg( feature="ssl" ) ]
@@ -208,14 +249,6 @@ impl Server<SslAcceptor> {
208
249
}
209
250
}
210
251
}
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
- }
219
252
}
220
253
221
254
#[ cfg( feature="ssl" ) ]
@@ -271,3 +304,36 @@ impl Iterator for Server<NoSslAcceptor> {
271
304
Some ( self . accept ( ) )
272
305
}
273
306
}
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