OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 /** | 7 /** |
8 * Web socket status codes used when closing a web socket connection. | 8 * Web socket status codes used when closing a web socket connection. |
9 */ | 9 */ |
10 abstract class WebSocketStatus { | 10 abstract class WebSocketStatus { |
11 static const int NORMAL_CLOSURE = 1000; | 11 static const int NORMAL_CLOSURE = 1000; |
12 static const int GOING_AWAY = 1001; | 12 static const int GOING_AWAY = 1001; |
13 static const int PROTOCOL_ERROR = 1002; | 13 static const int PROTOCOL_ERROR = 1002; |
14 static const int UNSUPPORTED_DATA = 1003; | 14 static const int UNSUPPORTED_DATA = 1003; |
15 static const int RESERVED_1004 = 1004; | 15 static const int RESERVED_1004 = 1004; |
16 static const int NO_STATUS_RECEIVED = 1005; | 16 static const int NO_STATUS_RECEIVED = 1005; |
17 static const int ABNORMAL_CLOSURE = 1006; | 17 static const int ABNORMAL_CLOSURE = 1006; |
18 static const int INVALID_FRAME_PAYLOAD_DATA = 1007; | 18 static const int INVALID_FRAME_PAYLOAD_DATA = 1007; |
19 static const int POLICY_VIOLATION = 1008; | 19 static const int POLICY_VIOLATION = 1008; |
20 static const int MESSAGE_TOO_BIG = 1009; | 20 static const int MESSAGE_TOO_BIG = 1009; |
21 static const int MISSING_MANDATORY_EXTENSION = 1010; | 21 static const int MISSING_MANDATORY_EXTENSION = 1010; |
22 static const int INTERNAL_SERVER_ERROR = 1011; | 22 static const int INTERNAL_SERVER_ERROR = 1011; |
23 static const int RESERVED_1015 = 1015; | 23 static const int RESERVED_1015 = 1015; |
24 } | 24 } |
25 | 25 |
26 /** | 26 /** |
27 * The web socket protocol is implemented by a HTTP or HTTPS server handler | 27 * The [WebSocketTransformer] is implemented as a stream transformer that |
28 * which can be instantiated like this: | 28 * transforms a stream of HttpRequest into a stream of WebSockets by upgrading |
| 29 * each HttpRequest from the HTTP or HTTPS server, to the WebSocket protocol. |
29 * | 30 * |
30 * WebSocketHandler wsHandler = new WebSocketHandler(); | 31 * Example of usage: |
31 * | 32 * |
32 * and then its onRequest method can be assigned to the HTTP server, e.g. | 33 * server.transform(new WebSocketTransformer()).listen((webSocket) => ...); |
33 * | |
34 * server.defaultHandler = wsHandler.onRequest; | |
35 * | 34 * |
36 * or | 35 * or |
37 * | 36 * |
38 * server.addRequestHandler((req) => req.path == "/ws", | 37 * server |
39 * wsHandler.onRequest); | 38 * .where((request) => request.uri.scheme == "ws") |
| 39 * .transform(new WebSocketTransformer()).listen((webSocket) => ...); |
40 * | 40 * |
41 * This handler strives to implement web sockets as specified by RFC6455. | 41 * This transformer strives to implement web sockets as specified by RFC6455. |
42 */ | 42 */ |
43 abstract class WebSocketHandler { | 43 abstract class WebSocketTransformer |
44 factory WebSocketHandler() => new _WebSocketHandler(); | 44 implements StreamTransformer<HttpRequest, WebSocket> { |
45 | 45 factory WebSocketTransformer() => new _WebSocketTransformerImpl(); |
46 /** | |
47 * Request handler to be registered with the HTTP server. | |
48 */ | |
49 void onRequest(HttpRequest request, HttpResponse response); | |
50 | |
51 /** | |
52 * Sets the callback to be called when a new web socket connection | |
53 * has been established. | |
54 */ | |
55 void set onOpen(callback(WebSocketConnection connection)); | |
56 } | 46 } |
57 | 47 |
58 | 48 |
59 /** | |
60 * Server web socket connection. | |
61 */ | |
62 abstract class WebSocketConnection { | |
63 /** | |
64 * Sets the callback to be called when a message has been | |
65 * received. The type on [message] is either [:String:] or | |
66 * [:List<int>:] depending on whether it is a text or binary | |
67 * message. If the message is empty [message] will be [:null:]. | |
68 * If [message] is a [:List<int>:] then it will contain byte values | |
69 * from 0 to 255. | |
70 */ | |
71 void set onMessage(void callback(message)); | |
72 | |
73 /** | |
74 * Sets the callback to be called when the web socket connection is | |
75 * closed. [status] indicate the reason for closing. For network | |
76 * errors the value of [status] will be | |
77 * WebSocketStatus.ABNORMAL_CLOSURE]. In this callback it is | |
78 * possible to call [close] if [close] has not already been called. | |
79 * If [close] has still not been called after the close callback | |
80 * returns the received close status will automatically be echoed | |
81 * back to the other end to finish the close handshake. | |
82 */ | |
83 void set onClosed(void callback(int status, String reason)); | |
84 | |
85 /** | |
86 * Sends a message. The [message] must be a [:String:], a | |
87 * [:List<int>:] containing bytes, or [:null:]. | |
88 */ | |
89 send(Object message); | |
90 | |
91 /** | |
92 * Close the web socket connection. The default value for [status] | |
93 * and [reason] are [:null:]. | |
94 */ | |
95 close([int status, String reason]); | |
96 } | |
97 | |
98 | |
99 /** | |
100 * Client web socket connection. | |
101 */ | |
102 abstract class WebSocketClientConnection { | |
103 /** | |
104 * Creates a new web socket client connection based on a HTTP(S) client | |
105 * connection. The HTTP or HTTPS client connection must be freshly opened. | |
106 */ | |
107 factory WebSocketClientConnection(HttpClientConnection conn, | |
108 [List<String> protocols]) { | |
109 return new _WebSocketClientConnection(conn, protocols); | |
110 } | |
111 | |
112 /** | |
113 * Sets the callback to be called when the request object for the | |
114 * opening handshake request is ready. This callback can be used if | |
115 * one needs to add additional headers to the opening handshake | |
116 * request. | |
117 */ | |
118 void set onRequest(void callback(HttpClientRequest request)); | |
119 | |
120 /** | |
121 * Sets the callback to be called when a web socket connection has | |
122 * been established. | |
123 */ | |
124 void set onOpen(void callback()); | |
125 | |
126 /** | |
127 * Sets the callback to be called when a message has been | |
128 * received. The type of [message] is either [:String:] or | |
129 * [:List<int>:], depending on whether it is a text or binary | |
130 * message. If the message is empty [message] will be [:null:]. | |
131 * If the message is a [:List<int>:] then it will contain byte values | |
132 * from 0 to 255. | |
133 */ | |
134 void set onMessage(void callback(message)); | |
135 | |
136 /** | |
137 * Sets the callback to be called when the web socket connection is | |
138 * closed. [status] indicates the reason for closing. For network | |
139 * errors the value of [status] will be | |
140 * WebSocketStatus.ABNORMAL_CLOSURE]. | |
141 */ | |
142 void set onClosed(void callback(int status, String reason)); | |
143 | |
144 /** | |
145 * Sets the callback to be called when the response object for the | |
146 * opening handshake did not cause a web socket connection | |
147 * upgrade. This will be called in case the response status code is | |
148 * not 101 (Switching Protocols). If this callback is not set and the | |
149 * server does not upgrade the connection, the [:onError:] callback will | |
150 * be called. | |
151 */ | |
152 void set onNoUpgrade(void callback(HttpClientResponse response)); | |
153 | |
154 /** | |
155 * Sends a message. The [message] must be a [:String:] or a | |
156 * [:List<int>:] containing bytes. To send an empty message send either | |
157 * an empty [:String:] or an empty [:List<int>:]. [:null:] cannot be sent. | |
158 */ | |
159 send(message); | |
160 | |
161 /** | |
162 * Close the web socket connection. The default value for [status] | |
163 * and [reason] are [:null:]. | |
164 */ | |
165 close([int status, String reason]); | |
166 } | |
167 | |
168 | |
169 /** | 49 /** |
170 * Base class for the events generated by the W3C complient browser | 50 * Base class for the events generated by the W3C complient browser |
171 * API for web sockets. | 51 * API for web sockets. |
172 */ | 52 */ |
173 abstract class Event { } | 53 abstract class Event { } |
174 | 54 |
175 /** | 55 /** |
176 * Event delivered when there is data on a web socket connection. | 56 * Event delivered when there is data on a web socket connection. |
177 */ | 57 */ |
178 abstract class MessageEvent extends Event { | 58 abstract class MessageEvent extends Event { |
179 /** | 59 /** |
180 * The type of [message] is either [:String:] or [:List<int>:] | 60 * The type of [message] is either [:String:] or [:List<int>:] |
181 * depending on whether it is a text or binary message. If the | 61 * depending on whether it is a text or binary message. If the |
182 * message is empty [message] will be [:null:] | 62 * message is empty [message] will be [:null:] |
183 * If the message is a [:List<int>:] then it will contain byte values | 63 * If the message is a [:List<int>:] then it will contain byte values |
184 * from 0 to 255. | 64 * from 0 to 255. |
185 | |
186 */ | 65 */ |
187 get data; | 66 get data; |
188 } | 67 } |
189 | 68 |
190 | 69 |
191 /** | 70 /** |
192 * Event delivered when a web socket connection is closed. | 71 * Event delivered when a web socket connection is closed. |
193 */ | 72 */ |
194 abstract class CloseEvent extends Event { | 73 abstract class CloseEvent extends Event { |
195 /** | 74 /** |
(...skipping 13 matching lines...) Expand all Loading... |
209 */ | 88 */ |
210 String get reason; | 89 String get reason; |
211 } | 90 } |
212 | 91 |
213 | 92 |
214 /** | 93 /** |
215 * Alternative web socket client interface. This interface is compliant | 94 * Alternative web socket client interface. This interface is compliant |
216 * with the W3C browser API for web sockets specified in | 95 * with the W3C browser API for web sockets specified in |
217 * http://dev.w3.org/html5/websockets/. | 96 * http://dev.w3.org/html5/websockets/. |
218 */ | 97 */ |
219 abstract class WebSocket { | 98 abstract class WebSocket implements Stream<Event> { |
220 /** | 99 /** |
221 * Possible states of the connection. | 100 * Possible states of the connection. |
222 */ | 101 */ |
223 static const int CONNECTING = 0; | 102 static const int CONNECTING = 0; |
224 static const int OPEN = 1; | 103 static const int OPEN = 1; |
225 static const int CLOSING = 2; | 104 static const int CLOSING = 2; |
226 static const int CLOSED = 3; | 105 static const int CLOSED = 3; |
227 | 106 |
228 /** | 107 /** |
229 * Create a new web socket connection. The URL supplied in [url] | 108 * Create a new web socket connection. The URL supplied in [url] |
230 * must use the scheme [:ws:]. The [protocols] argument is either a | 109 * must use the scheme [:ws:] or [:wss:]. The [protocols] argument is either |
231 * [:String:] or [:List<String>:] specifying the subprotocols the | 110 * a [:String:] or [:List<String>:] specifying the subprotocols the |
232 * client is willing to speak. | 111 * client is willing to speak. |
233 */ | 112 */ |
234 factory WebSocket(String url, [protocols]) => new _WebSocket(url, protocols); | 113 static Future<WebSocket> connect(String url, [protocols]) => |
| 114 _WebSocketImpl.connect(url, protocols); |
235 | 115 |
236 /** | 116 /** |
237 * Returns the current state of the connection. | 117 * Returns the current state of the connection. |
238 */ | 118 */ |
239 int get readyState; | 119 int get readyState; |
240 | 120 |
241 /** | 121 /** |
242 * Returns the number of bytes currently buffered for transmission. | 122 * Returns the number of bytes currently buffered for transmission. |
243 */ | 123 */ |
244 int get bufferedAmount; | 124 int get bufferedAmount; |
245 | 125 |
246 /** | 126 /** |
247 * Sets the callback to be called when a web socket connection has | |
248 * been established. | |
249 */ | |
250 void set onopen(void callback()); | |
251 | |
252 /** | |
253 * Sets the callback to be called when the web socket connection | |
254 * encountered an error. | |
255 */ | |
256 void set onerror(void callback(e)); | |
257 | |
258 /** | |
259 * Sets the callback to be called when the web socket connection is | |
260 * closed. | |
261 */ | |
262 void set onclose(void callback(CloseEvent event)); | |
263 | |
264 /** | |
265 * The extensions property is initially the empty string. After the | 127 * The extensions property is initially the empty string. After the |
266 * web socket connection is established this string reflects the | 128 * web socket connection is established this string reflects the |
267 * extensions used by the server. | 129 * extensions used by the server. |
268 */ | 130 */ |
269 String get extensions; | 131 String get extensions; |
270 | 132 |
271 /** | 133 /** |
272 * The protocol property is initially the empty string. After the | 134 * The protocol property is initially the empty string. After the |
273 * web socket connection is established the value is the subprotocol | 135 * web socket connection is established the value is the subprotocol |
274 * selected by the server. If no subprotocol is negotiated the | 136 * selected by the server. If no subprotocol is negotiated the |
275 * value will remain [:null:]. | 137 * value will remain [:null:]. |
276 */ | 138 */ |
277 String get protocol; | 139 String get protocol; |
278 | 140 |
279 /** | 141 /** |
280 * Closes the web socket connection. | 142 * Closes the web socket connection. |
281 */ | 143 */ |
282 void close(int code, String reason); | 144 void close([int code, String reason]); |
283 | |
284 /** | |
285 * Sets the callback to be called when a message has been | |
286 * received. | |
287 */ | |
288 void set onmessage(void callback(MessageEvent event)); | |
289 | 145 |
290 /** | 146 /** |
291 * Sends data on the web socket connection. The data in [data] must | 147 * Sends data on the web socket connection. The data in [data] must |
292 * be either a [:String:], or a [:List<int>:] holding bytes. | 148 * be either a [:String:], or a [:List<int>:] holding bytes. |
293 */ | 149 */ |
294 void send(data); | 150 void send(data); |
295 } | 151 } |
296 | 152 |
297 | 153 |
298 class WebSocketException implements Exception { | 154 class WebSocketException implements Exception { |
299 const WebSocketException([String this.message = ""]); | 155 const WebSocketException([String this.message = ""]); |
300 String toString() => "WebSocketException: $message"; | 156 String toString() => "WebSocketException: $message"; |
301 final String message; | 157 final String message; |
302 } | 158 } |
OLD | NEW |