Update WS Documentation (#145)

* update examples in docs to show upgrade, provide on_ methods

* add clarification
pull/150/head
Will Rieger 2023-11-29 06:30:51 -05:00 zatwierdzone przez GitHub
rodzic e8b4c21515
commit e6710b6a9e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
1 zmienionych plików z 102 dodań i 4 usunięć

Wyświetl plik

@ -3,6 +3,52 @@ WebSocket "routes" are registered similarly, but not identically.
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:
Configuration details, notes:
- *idle_timeout*: number of seconds of inactivity before client is disconnected. If set to 0, no policy is enforced (connections can be stale).
- *open*: callback function for websocket connection being open
```python
def on_open(ws : WebSocket):
"""
ws: WebSocket - websocket connection
"""
...
```
- *close*: callback function for websocket connection closed
```python
def on_close(ws: WebSocket, code: int, msg: Union[bytes, str]):
"""
ws: WebSocket
websocket connection
code: int
exit code from client
msg: byte, str
exit message
"""
...
```
- *upgrade*: callback function to upgrade socket connection details
```python
def on_upgrade(res: Response, req: Request, socket_context):
"""
res: Response
req: Request
"""
...
```
- *message*: callback function for websocket message received
```python
def on_message(ws: WebSocket, msg: Union[bytes, str], opcode: OpCode):
"""
ws: WebSocket
msg: bytes, str
opcode: OpCode
"""
```
- *drain*: in the event of backpressure, policy to drain ws buffer
```python
def on_drain(ws: WebSocket):
...
```
```python
app = App()
app.ws(
@ -11,10 +57,11 @@ app.ws(
"compression": CompressOptions.SHARED_COMPRESSOR,
"max_payload_length": 16 * 1024 * 1024,
"idle_timeout": 12,
"open": ws_open,
"message": ws_message,
'drain': lambda ws: print(f'WebSocket backpressure: {ws.get_buffered_amount()}'),
"close": lambda ws, code, message: print("WebSocket closed"),
"open": on_open,
"message": on_message,
"close": on_close,
"upgrade": on_upgrade,
'drain': on_drain,
"subscription": lambda ws, topic, subscriptions, subscriptions_before: print(f'subscription/unsubscription on topic {topic} {subscriptions} {subscriptions_before}'),
},
)
@ -24,6 +71,57 @@ You should use the provided user data feature to store and attach any per-socket
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.
In order to do so, use the `upgrade` callback configuration in the `app.ws` settings.
Example:
```python
from socketify import App, WebSocket, OpCode
app = App()
ID = 0
def on_open(ws: WebSocket):
user_data = ws.get_user_data()
print('ws %s connected' % user_data['user_id'])
ws.send('Hello, world!')
def on_upgrade(res, req, socket_context):
global ID
ID += 1
key = req.get_header("sec-websocket-key")
protocol = req.get_header("sec-websocket-protocol")
extensions = req.get_header("sec-websocket-extensions")
user_data=dict(user_id=ID)
res.upgrade(key, protocol, extensions, socket_context, user_data)
def on_message(ws: WebSocket, msg: str, opcode: OpCode):
user_data = ws.get_user_data()
print('ws %s: %s' % (user_data['user_id'], msg))
def on_close(ws, code, msg):
user_data = ws.get_user_data()
print('ws %s closed' % user_data['user_id'])
def on_drain(ws: WebSocket):
user_data = ws.get_user_data()
print('ws %s backpressure: %s' % (user_data['user_id'], ws.get_buffered_amount()))
app.ws(
"/*",
{
"compression": CompressOptions.SHARED_COMPRESSOR,
"max_payload_length": 16 * 1024 * 1024,
"idle_timeout": 12,
"open": on_open,
"message": on_message,
"close": on_close,
"upgrade": on_upgrade,
"drain": on_drain,
"subscription": lambda ws, topic, subscriptions, subscriptions_before: print(f'subscription/unsubscription on topic {topic} {subscriptions} {subscriptions_before}'),
}
)
```
## WebSockets are valid from open to close
All given WebSocket are guaranteed to live from open event (where you got your WebSocket) until close event is called.
Message events will never emit outside of open/close. Calling ws.close or ws.end will immediately call the close handler.