Sanic with websocket
依赖环境
toml
[tool.poetry.dependencies]
python = "^3.9"
sanic = "^23.6.0"
代码
python
from sanic import Sanic, Request, Websocket
from sanic.response import json as resp_json
import json
app = Sanic("app")
SECRET = 'test-test-test'
@app.get("/")
async def index(r: Request):
return resp_json({"message": "success"}, status=200)
class WsHandle:
def __init__(self, ws):
self.ws = ws
async def recv(self, msg_recv):
print(f'[recv] {msg_recv}')
data = json.loads(msg_recv)
index = data.get('index')
return index, data
async def close(self):
await self.ws.close()
async def send(self, index, data_send):
data_send_ = {'index': index+1}
data_send_.update(data_send)
msg_send = json.dumps(data_send_)
print(f'[send] {msg_send}')
await self.ws.send(msg_send)
@app.websocket("/feed")
async def feed(request: Request, ws: Websocket):
print('new ws connection')
async for msg_recv in ws:
h = WsHandle(ws)
index, data = await h.recv(msg_recv)
# do something
message = data.get('message')
data_send = {'message':message}
await h.send(index, data_send)
if __name__ == '__main__':
app.run(host="127.0.0.1", port=80, access_log=True, auto_reload=True)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Client</title>
</head>
<body>
<script>
class MsgHandle {
constructor(ws) {
this.ws = ws
}
Recv(recv_data) {
const data = JSON.parse(recv_data);
let index = data.index;
return { index, data }
}
Send(index, data) {
this.ws.send(JSON.stringify({ index: index + 1, ...data }));
}
sleep(time) {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}
async SendWait(index, data, wait_time_ms) {
await this.sleep(wait_time_ms);
this.Send(index, data)
}
}
const URL_WS = 'ws://127.0.0.1:80/feed';
const socket = new WebSocket(URL_WS);
const mh = new MsgHandle(socket);
socket.addEventListener('open', (event) => {
console.log('WebSocket连接已打开');
mh.Send(-1, { message: "init" })
});
socket.addEventListener('message', async (event) => {
let { index, data } = mh.Recv(event.data);
await mh.SendWait(index, { message: "hello" }, 3000);
});
socket.addEventListener('close', (event) => {
console.log('WebSocket连接已关闭');
});
socket.addEventListener('error', (event) => {
console.error('WebSocket连接错误:', event);
});
</script>
</body>
</html>