0
# Synchronous WebSocket
1
2
Synchronous WebSocket implementation providing thread-based WebSocket server and client functionality. These classes handle WebSocket connections using traditional blocking I/O operations with background threads managing the connection lifecycle.
3
4
## Capabilities
5
6
### Server Class
7
8
WebSocket server that accepts connections from WSGI environments. Automatically detects the web server type (Werkzeug, Gunicorn, Eventlet, Gevent) and extracts the underlying socket for WebSocket communication.
9
10
```python { .api }
11
class Server:
12
def __init__(self, environ, subprotocols=None, receive_bytes=4096,
13
ping_interval=None, max_message_size=None, thread_class=None,
14
event_class=None, selector_class=None):
15
"""
16
Initialize WebSocket server from WSGI environ.
17
18
Parameters:
19
- environ: WSGI environ dictionary containing request details and socket
20
- subprotocols: List of supported subprotocols or None
21
- receive_bytes: Buffer size for receiving data (default: 4096)
22
- ping_interval: Ping interval in seconds or None to disable
23
- max_message_size: Maximum message size in bytes or None for no limit
24
- thread_class: Thread class to use (default: threading.Thread)
25
- event_class: Event class to use (default: threading.Event)
26
- selector_class: Selector class to use (default: selectors.DefaultSelector)
27
"""
28
```
29
30
```python { .api }
31
@classmethod
32
def accept(cls, environ, subprotocols=None, receive_bytes=4096,
33
ping_interval=None, max_message_size=None, thread_class=None,
34
event_class=None, selector_class=None):
35
"""
36
Accept WebSocket connection from client.
37
38
Parameters:
39
- environ: WSGI environ dictionary with request details and socket
40
- subprotocols: List of supported subprotocols or None to disable negotiation
41
- receive_bytes: Buffer size for receiving data (default: 4096)
42
- ping_interval: Send ping packets at this interval in seconds or None
43
- max_message_size: Maximum allowed message size in bytes or None
44
- thread_class: Thread class for background operations
45
- event_class: Event class for synchronization
46
- selector_class: Selector class for I/O multiplexing
47
48
Returns:
49
Server instance connected to the client
50
"""
51
```
52
53
### Server Methods
54
55
```python { .api }
56
def send(self, data):
57
"""
58
Send data over the WebSocket connection.
59
60
Parameters:
61
- data: Data to send (str for text message, bytes for binary message)
62
"""
63
64
def receive(self, timeout=None):
65
"""
66
Receive data over the WebSocket connection.
67
68
Parameters:
69
- timeout: Timeout in seconds (None for indefinite, 0 for non-blocking)
70
71
Returns:
72
Received data as str or bytes depending on message type
73
"""
74
75
def close(self, reason=None, message=None):
76
"""
77
Close the WebSocket connection.
78
79
Parameters:
80
- reason: Numeric status code for closure (default: 1000 normal closure)
81
- message: Text message to send with closure
82
"""
83
84
def choose_subprotocol(self, request):
85
"""
86
Choose subprotocol for the WebSocket connection.
87
88
Parameters:
89
- request: Request object containing client's requested subprotocols
90
91
Returns:
92
Selected subprotocol name or None if no subprotocol chosen
93
"""
94
```
95
96
### Client Class
97
98
WebSocket client that connects to WebSocket servers using ws:// or wss:// URLs. Handles SSL/TLS connections automatically and supports custom headers and subprotocol negotiation.
99
100
```python { .api }
101
class Client:
102
def __init__(self, url, subprotocols=None, headers=None, receive_bytes=4096,
103
ping_interval=None, max_message_size=None, ssl_context=None,
104
thread_class=None, event_class=None):
105
"""
106
Initialize WebSocket client.
107
108
Parameters:
109
- url: WebSocket URL to connect to (ws:// or wss://)
110
- subprotocols: Subprotocol name or list of names to request
111
- headers: Additional HTTP headers as dict or list of tuples
112
- receive_bytes: Buffer size for receiving data (default: 4096)
113
- ping_interval: Ping interval in seconds or None to disable
114
- max_message_size: Maximum message size in bytes or None for no limit
115
- ssl_context: SSL context for secure connections or None for default
116
- thread_class: Thread class to use (default: threading.Thread)
117
- event_class: Event class to use (default: threading.Event)
118
"""
119
```
120
121
```python { .api }
122
@classmethod
123
def connect(cls, url, subprotocols=None, headers=None, receive_bytes=4096,
124
ping_interval=None, max_message_size=None, ssl_context=None,
125
thread_class=None, event_class=None):
126
"""
127
Create and connect WebSocket client.
128
129
Parameters:
130
- url: WebSocket URL (ws:// or wss://)
131
- subprotocols: Subprotocol name or list of preference-ordered names
132
- headers: Additional HTTP headers as dict or list of tuples
133
- receive_bytes: Buffer size for receiving data (default: 4096)
134
- ping_interval: Send ping packets at this interval in seconds or None
135
- max_message_size: Maximum allowed message size in bytes or None
136
- ssl_context: Custom SSL context or None for default secure context
137
- thread_class: Thread class for background operations
138
- event_class: Event class for synchronization
139
140
Returns:
141
Connected Client instance
142
"""
143
```
144
145
### Client Methods
146
147
```python { .api }
148
def send(self, data):
149
"""
150
Send data over the WebSocket connection.
151
152
Parameters:
153
- data: Data to send (str for text message, bytes for binary message)
154
"""
155
156
def receive(self, timeout=None):
157
"""
158
Receive data over the WebSocket connection.
159
160
Parameters:
161
- timeout: Timeout in seconds (None for indefinite, 0 for non-blocking)
162
163
Returns:
164
Received data as str or bytes depending on message type
165
"""
166
167
def close(self, reason=None, message=None):
168
"""
169
Close the WebSocket connection and underlying socket.
170
171
Parameters:
172
- reason: Numeric status code for closure (default: 1000 normal closure)
173
- message: Text message to send with closure
174
"""
175
```
176
177
## Usage Examples
178
179
### Basic Server Usage
180
181
```python
182
import simple_websocket
183
184
def websocket_handler(environ, start_response):
185
# Accept WebSocket connection
186
ws = simple_websocket.Server.accept(environ)
187
188
try:
189
while True:
190
# Receive message from client
191
message = ws.receive(timeout=30) # 30 second timeout
192
if message is None:
193
break # Timeout occurred
194
195
# Echo message back to client
196
ws.send(f"Echo: {message}")
197
198
except simple_websocket.ConnectionClosed:
199
print("Client disconnected")
200
except simple_websocket.ConnectionError as e:
201
print(f"Connection error: {e}")
202
finally:
203
ws.close()
204
```
205
206
### Basic Client Usage
207
208
```python
209
import simple_websocket
210
211
try:
212
# Connect to WebSocket server
213
ws = simple_websocket.Client.connect("ws://localhost:8000/ws")
214
215
# Send message
216
ws.send("Hello, Server!")
217
218
# Receive response
219
response = ws.receive(timeout=10)
220
print(f"Server response: {response}")
221
222
except simple_websocket.ConnectionError as e:
223
print(f"Failed to connect: {e}")
224
except simple_websocket.ConnectionClosed:
225
print("Server closed connection")
226
finally:
227
ws.close()
228
```
229
230
### Subprotocol Negotiation
231
232
```python
233
# Server with custom subprotocol selection
234
class MyServer(simple_websocket.Server):
235
def choose_subprotocol(self, request):
236
# Custom logic for subprotocol selection
237
if 'chat' in request.subprotocols:
238
return 'chat'
239
elif 'echo' in request.subprotocols:
240
return 'echo'
241
return None
242
243
# Accept connection with subprotocol support
244
ws = MyServer.accept(environ, subprotocols=['chat', 'echo'])
245
print(f"Negotiated subprotocol: {ws.subprotocol}")
246
247
# Client requesting specific subprotocols
248
ws = simple_websocket.Client.connect(
249
"ws://localhost:8000/ws",
250
subprotocols=['chat', 'echo']
251
)
252
print(f"Server selected subprotocol: {ws.subprotocol}")
253
```
254
255
## Types
256
257
### Base Class Attributes
258
259
```python { .api }
260
class Base:
261
subprotocol: str | None # Negotiated subprotocol name
262
connected: bool # Connection status
263
receive_bytes: int # Buffer size for receiving data
264
ping_interval: float | None # Ping interval in seconds
265
max_message_size: int | None # Maximum message size limit
266
```