0
# WebSocket Protocol Implementation
1
2
Complete RFC 6455 WebSocket implementation providing both client and server functionality with extensive protocol options, message compression, frame-level API access, and streaming capabilities.
3
4
## Capabilities
5
6
### WebSocket Server Protocol
7
8
Server-side WebSocket protocol implementation handling connection handshakes, message processing, and connection lifecycle management.
9
10
```python { .api }
11
class WebSocketServerProtocol:
12
def onConnect(self, request: ConnectionRequest) -> None:
13
"""
14
Called when WebSocket connection request is received.
15
16
Parameters:
17
- request: ConnectionRequest with peer, headers, host, path, params, version, origin, protocols, extensions
18
19
Returns:
20
None, ConnectionAccept, or ConnectionDeny
21
"""
22
23
def onOpen(self) -> None:
24
"""Called when WebSocket connection is established."""
25
26
def sendMessage(self, payload: bytes, isBinary: bool = False) -> None:
27
"""
28
Send WebSocket message.
29
30
Parameters:
31
- payload: Message data
32
- isBinary: True for binary message, False for text
33
"""
34
35
def onMessage(self, payload: bytes, isBinary: bool) -> None:
36
"""
37
Called when WebSocket message is received.
38
39
Parameters:
40
- payload: Message data
41
- isBinary: True for binary message, False for text
42
"""
43
44
def sendClose(self, code: int = None, reason: str = None) -> None:
45
"""
46
Initiate WebSocket close handshake.
47
48
Parameters:
49
- code: Close status code
50
- reason: Close reason string
51
"""
52
53
def onClose(self, wasClean: bool, code: int, reason: str) -> None:
54
"""
55
Called when WebSocket connection is closed.
56
57
Parameters:
58
- wasClean: True if closed cleanly
59
- code: Close status code
60
- reason: Close reason string
61
"""
62
63
def sendPing(self, payload: bytes = None) -> None:
64
"""Send WebSocket ping frame."""
65
66
def onPing(self, payload: bytes) -> None:
67
"""Called when ping frame received."""
68
69
def sendPong(self, payload: bytes = None) -> None:
70
"""Send WebSocket pong frame."""
71
72
def onPong(self, payload: bytes) -> None:
73
"""Called when pong frame received."""
74
```
75
76
### WebSocket Client Protocol
77
78
Client-side WebSocket protocol implementation for connecting to WebSocket servers.
79
80
```python { .api }
81
class WebSocketClientProtocol:
82
def onConnect(self, response: ConnectionResponse) -> None:
83
"""
84
Called when WebSocket handshake response received.
85
86
Parameters:
87
- response: ConnectionResponse with peer, headers, version, protocol, extensions
88
"""
89
90
def onOpen(self) -> None:
91
"""Called when WebSocket connection is established."""
92
93
def sendMessage(self, payload: bytes, isBinary: bool = False) -> None:
94
"""
95
Send WebSocket message.
96
97
Parameters:
98
- payload: Message data
99
- isBinary: True for binary message, False for text
100
"""
101
102
def onMessage(self, payload: bytes, isBinary: bool) -> None:
103
"""
104
Called when WebSocket message is received.
105
106
Parameters:
107
- payload: Message data
108
- isBinary: True for binary message, False for text
109
"""
110
111
def sendClose(self, code: int = None, reason: str = None) -> None:
112
"""Initiate WebSocket close handshake."""
113
114
def onClose(self, wasClean: bool, code: int, reason: str) -> None:
115
"""Called when WebSocket connection is closed."""
116
117
def sendPing(self, payload: bytes = None) -> None:
118
"""Send WebSocket ping frame."""
119
120
def onPing(self, payload: bytes) -> None:
121
"""Called when ping frame received."""
122
123
def sendPong(self, payload: bytes = None) -> None:
124
"""Send WebSocket pong frame."""
125
126
def onPong(self, payload: bytes) -> None:
127
"""Called when pong frame received."""
128
```
129
130
### WebSocket Factories
131
132
Factory classes for creating WebSocket protocol instances with configuration and protocol options.
133
134
```python { .api }
135
class WebSocketServerFactory:
136
def __init__(
137
self,
138
url: str = None,
139
protocols: list = None,
140
server: str = None,
141
headers: dict = None,
142
externalPort: int = None
143
):
144
"""
145
WebSocket server factory.
146
147
Parameters:
148
- url: WebSocket server URL
149
- protocols: List of supported subprotocols
150
- server: Server identifier string
151
- headers: Additional HTTP headers
152
- externalPort: External port number
153
"""
154
155
def setProtocolOptions(
156
self,
157
allowHixie76: bool = None,
158
webStatus: bool = None,
159
utf8validateIncoming: bool = None,
160
maskServerFrames: bool = None,
161
requireMaskedClientFrames: bool = None,
162
applyMask: bool = None,
163
maxFramePayloadSize: int = None,
164
maxMessagePayloadSize: int = None,
165
autoFragmentSize: int = None,
166
failByDrop: bool = None,
167
echoCloseCodeReason: bool = None,
168
openHandshakeTimeout: float = None,
169
closeHandshakeTimeout: float = None,
170
tcpNoDelay: bool = None,
171
perMessageCompressionAccept: callable = None,
172
perMessageCompressionOffers: list = None,
173
perMessageCompressionRaw: bool = None,
174
compression: str = None
175
) -> None:
176
"""Set WebSocket protocol options."""
177
178
class WebSocketClientFactory:
179
def __init__(
180
self,
181
url: str = None,
182
origin: str = None,
183
protocols: list = None,
184
useragent: str = None,
185
headers: dict = None,
186
proxy: dict = None
187
):
188
"""
189
WebSocket client factory.
190
191
Parameters:
192
- url: WebSocket server URL to connect to
193
- origin: Origin header value
194
- protocols: List of requested subprotocols
195
- useragent: User-Agent header value
196
- headers: Additional HTTP headers
197
- proxy: Proxy configuration
198
"""
199
200
def setProtocolOptions(
201
self,
202
version: int = None,
203
utf8validateIncoming: bool = None,
204
acceptMaskedServerFrames: bool = None,
205
maskClientFrames: bool = None,
206
applyMask: bool = None,
207
maxFramePayloadSize: int = None,
208
maxMessagePayloadSize: int = None,
209
autoFragmentSize: int = None,
210
failByDrop: bool = None,
211
echoCloseCodeReason: bool = None,
212
serverConnectionDropTimeout: float = None,
213
openHandshakeTimeout: float = None,
214
closeHandshakeTimeout: float = None,
215
tcpNoDelay: bool = None,
216
perMessageCompressionOffers: list = None,
217
perMessageCompressionAccept: callable = None,
218
compression: str = None
219
) -> None:
220
"""Set WebSocket protocol options."""
221
```
222
223
### Advanced Frame API
224
225
Frame-level API for applications requiring fine-grained control over WebSocket message framing.
226
227
```python { .api }
228
class IWebSocketChannelFrameApi:
229
def onMessageBegin(self, isBinary: bool) -> None:
230
"""Called when WebSocket message begins."""
231
232
def onMessageFrame(self, payload: bytes) -> None:
233
"""Called when complete message frame received."""
234
235
def onMessageEnd(self) -> None:
236
"""Called when WebSocket message ends."""
237
238
def beginMessage(self, isBinary: bool = False, doNotCompress: bool = False) -> None:
239
"""Begin sending fragmented message."""
240
241
def sendMessageFrame(self, payload: bytes, sync: bool = False) -> None:
242
"""Send message frame."""
243
244
def endMessage(self) -> None:
245
"""End fragmented message."""
246
```
247
248
### Streaming API
249
250
Streaming API for processing WebSocket messages as data streams rather than complete messages.
251
252
```python { .api }
253
class IWebSocketChannelStreamingApi:
254
def onMessageFrameBegin(self, length: int) -> None:
255
"""Called when message frame begins."""
256
257
def onMessageFrameData(self, payload: bytes) -> None:
258
"""Called when frame data received."""
259
260
def onMessageFrameEnd(self) -> None:
261
"""Called when message frame ends."""
262
263
def beginMessageFrame(self, length: int) -> None:
264
"""Begin sending message frame."""
265
266
def sendMessageFrameData(self, payload: bytes, sync: bool = False) -> None:
267
"""Send frame data."""
268
```
269
270
## Types
271
272
### Connection Types
273
274
```python { .api }
275
class ConnectionRequest:
276
peer: str # Remote peer address
277
headers: dict # HTTP headers
278
host: str # Host header value
279
path: str # Request path
280
params: dict # Query parameters
281
version: int # WebSocket version
282
origin: str # Origin header
283
protocols: list # Requested subprotocols
284
extensions: list # Requested extensions
285
286
class ConnectionResponse:
287
peer: str # Remote peer address
288
headers: dict # HTTP response headers
289
version: int # WebSocket version
290
protocol: str # Selected subprotocol
291
extensions: list # Negotiated extensions
292
293
class ConnectionAccept:
294
def __init__(self, subprotocol: str = None, headers: list = None): ...
295
296
class ConnectionDeny(Exception):
297
def __init__(self, code: int, reason: str = None): ...
298
```
299
300
### Message Types
301
302
```python { .api }
303
class Message:
304
payload: bytes # Message payload
305
is_binary: bool # Binary message flag
306
307
class IncomingMessage(Message):
308
payload: bytes # Incoming message data
309
is_binary: bool # True for binary, False for text
310
311
class OutgoingMessage(Message):
312
payload: bytes # Outgoing message data
313
is_binary: bool # Message type flag
314
skip_compress: bool # Skip compression flag
315
316
class Ping:
317
def __init__(self, payload: bytes = None): ...
318
```
319
320
## Usage Examples
321
322
### Basic WebSocket Server
323
324
```python
325
import asyncio
326
from autobahn.asyncio.websocket import WebSocketServerProtocol, WebSocketServerFactory
327
328
class EchoServerProtocol(WebSocketServerProtocol):
329
def onMessage(self, payload, isBinary):
330
# Echo back received message
331
self.sendMessage(payload, isBinary)
332
333
factory = WebSocketServerFactory("ws://localhost:9000")
334
factory.protocol = EchoServerProtocol
335
336
loop = asyncio.get_event_loop()
337
coro = loop.create_server(factory, '0.0.0.0', 9000)
338
server = loop.run_until_complete(coro)
339
loop.run_forever()
340
```
341
342
### WebSocket Client with Subprotocol
343
344
```python
345
import asyncio
346
from autobahn.asyncio.websocket import WebSocketClientProtocol, WebSocketClientFactory
347
348
class MyClientProtocol(WebSocketClientProtocol):
349
def onOpen(self):
350
self.sendMessage(b"Hello Server!", isBinary=False)
351
352
def onMessage(self, payload, isBinary):
353
print(f"Received: {payload.decode('utf8')}")
354
355
factory = WebSocketClientFactory("ws://localhost:9000", protocols=["chat"])
356
factory.protocol = MyClientProtocol
357
358
loop = asyncio.get_event_loop()
359
coro = loop.create_connection(factory, '127.0.0.1', 9000)
360
loop.run_until_complete(coro)
361
loop.run_forever()
362
```
363
364
### Connection Handling
365
366
```python
367
class SelectiveServerProtocol(WebSocketServerProtocol):
368
def onConnect(self, request):
369
# Accept only connections from localhost
370
if request.peer != '127.0.0.1':
371
raise ConnectionDeny(403, "Forbidden")
372
373
# Select subprotocol
374
if 'chat' in request.protocols:
375
return ConnectionAccept(subprotocol='chat')
376
377
return ConnectionAccept()
378
```