Skip to content

Commit e6710b6

Browse files
authored
Update WS Documentation (#145)
* update examples in docs to show upgrade, provide on_ methods * add clarification
1 parent e8b4c21 commit e6710b6

File tree

1 file changed

+102
-4
lines changed

1 file changed

+102
-4
lines changed

docs/websockets-backpressure.md

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,52 @@ WebSocket "routes" are registered similarly, but not identically.
33

44
Every websocket route has the same pattern and pattern matching as for Http, but instead of one single callback you have a whole set of them, here's an example:
55

6+
Configuration details, notes:
7+
- *idle_timeout*: number of seconds of inactivity before client is disconnected. If set to 0, no policy is enforced (connections can be stale).
8+
- *open*: callback function for websocket connection being open
9+
```python
10+
def on_open(ws : WebSocket):
11+
"""
12+
ws: WebSocket - websocket connection
13+
"""
14+
...
15+
```
16+
- *close*: callback function for websocket connection closed
17+
```python
18+
def on_close(ws: WebSocket, code: int, msg: Union[bytes, str]):
19+
"""
20+
ws: WebSocket
21+
websocket connection
22+
code: int
23+
exit code from client
24+
msg: byte, str
25+
exit message
26+
"""
27+
...
28+
```
29+
- *upgrade*: callback function to upgrade socket connection details
30+
```python
31+
def on_upgrade(res: Response, req: Request, socket_context):
32+
"""
33+
res: Response
34+
req: Request
35+
"""
36+
...
37+
```
38+
- *message*: callback function for websocket message received
39+
```python
40+
def on_message(ws: WebSocket, msg: Union[bytes, str], opcode: OpCode):
41+
"""
42+
ws: WebSocket
43+
msg: bytes, str
44+
opcode: OpCode
45+
"""
46+
```
47+
- *drain*: in the event of backpressure, policy to drain ws buffer
48+
```python
49+
def on_drain(ws: WebSocket):
50+
...
51+
```
652
```python
753
app = App()
854
app.ws(
@@ -11,10 +57,11 @@ app.ws(
1157
"compression": CompressOptions.SHARED_COMPRESSOR,
1258
"max_payload_length": 16 * 1024 * 1024,
1359
"idle_timeout": 12,
14-
"open": ws_open,
15-
"message": ws_message,
16-
'drain': lambda ws: print(f'WebSocket backpressure: {ws.get_buffered_amount()}'),
17-
"close": lambda ws, code, message: print("WebSocket closed"),
60+
"open": on_open,
61+
"message": on_message,
62+
"close": on_close,
63+
"upgrade": on_upgrade,
64+
'drain': on_drain,
1865
"subscription": lambda ws, topic, subscriptions, subscriptions_before: print(f'subscription/unsubscription on topic {topic} {subscriptions} {subscriptions_before}'),
1966
},
2067
)
@@ -24,6 +71,57 @@ You should use the provided user data feature to store and attach any per-socket
2471

2572
If you want to create something more elaborate you could have the user data hold a pointer to some dynamically allocated memory block that keeps a boolean whether the WebSocket is still valid or not. Sky is the limit here.
2673

74+
In order to do so, use the `upgrade` callback configuration in the `app.ws` settings.
75+
76+
Example:
77+
```python
78+
from socketify import App, WebSocket, OpCode
79+
app = App()
80+
81+
ID = 0
82+
83+
def on_open(ws: WebSocket):
84+
user_data = ws.get_user_data()
85+
print('ws %s connected' % user_data['user_id'])
86+
ws.send('Hello, world!')
87+
88+
def on_upgrade(res, req, socket_context):
89+
global ID
90+
ID += 1
91+
key = req.get_header("sec-websocket-key")
92+
protocol = req.get_header("sec-websocket-protocol")
93+
extensions = req.get_header("sec-websocket-extensions")
94+
user_data=dict(user_id=ID)
95+
res.upgrade(key, protocol, extensions, socket_context, user_data)
96+
97+
def on_message(ws: WebSocket, msg: str, opcode: OpCode):
98+
user_data = ws.get_user_data()
99+
print('ws %s: %s' % (user_data['user_id'], msg))
100+
101+
def on_close(ws, code, msg):
102+
user_data = ws.get_user_data()
103+
print('ws %s closed' % user_data['user_id'])
104+
105+
def on_drain(ws: WebSocket):
106+
user_data = ws.get_user_data()
107+
print('ws %s backpressure: %s' % (user_data['user_id'], ws.get_buffered_amount()))
108+
109+
app.ws(
110+
"/*",
111+
{
112+
"compression": CompressOptions.SHARED_COMPRESSOR,
113+
"max_payload_length": 16 * 1024 * 1024,
114+
"idle_timeout": 12,
115+
"open": on_open,
116+
"message": on_message,
117+
"close": on_close,
118+
"upgrade": on_upgrade,
119+
"drain": on_drain,
120+
"subscription": lambda ws, topic, subscriptions, subscriptions_before: print(f'subscription/unsubscription on topic {topic} {subscriptions} {subscriptions_before}'),
121+
}
122+
)
123+
```
124+
27125
## WebSockets are valid from open to close
28126
All given WebSocket are guaranteed to live from open event (where you got your WebSocket) until close event is called.
29127
Message events will never emit outside of open/close. Calling ws.close or ws.end will immediately call the close handler.

0 commit comments

Comments
 (0)