在之前的工作中,由于涉及到websocket及时响应的交互式接口编写费了较大力,因此本次主要分享一下websocket接口,主体仍然调用fastapi框架完成,先上代码。
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
host = 'localhost'
port = 8000
app = FastAPI()
# 初始化测试界面
html = """<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head>
<title>Chat</title>
</head>
<body>
<h1>WebSocket Chat</h1>
<form action="" onsubmit="sendMessage(event)">
<!-- <input type="text" id="messageText" autocomplete="off"/>-->
<textarea rows="5" id="messageText"></textarea>
<button>Send</button>
</form>
<ul id='messages'>
</ul>
<script>
var ws = new WebSocket("ws://%s:%s/ws");
ws.onmessage = function(event) {
var messages = document.getElementById('messages')
var message = document.createElement('li')
var content = document.createTextNode(event.data)
message.appendChild(content)
messages.appendChild(message)
};
function sendMessage(event) {
var input = document.getElementById("messageText")
ws.send(input.value)
input.value = ''
event.preventDefault()
}
</script>
</body>
</html>""" % (host, port)
# 请求初始页面
@app.get("/")
async def get():
return HTMLResponse(html)
# websocket接口
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
i = 0
while True:
data = await websocket.receive_text()
i = i + 1
await websocket.send_text(f" This is {i} recept, Message text was: {data}")
# 测试主体
if __name__ == '__main__':
import uvicorn
uvicorn.run('websocket:app', host=host, port=port, reload=True, workers=1)
为了实现交互式测试,首先编写了一段html网页文件,初始化测试页面代码,其次通过get请求到该网页结构并渲染,实现测试界面的初始化。
完成上述代码后,正式进入websocket接口定义。用/ws路由指向接口,创建websocket对话后,首先等待连接,当连接成功后,即可通过receive函数接受前端请求,send_text函数向前端返回数据,实现异步的数据交互作用。其中i的主要作用是计次。
需要提示的是,在这段代码中,网页内容是提前初始化好的,可以发现在script语句中,创建WebSocket对象时( var ws = new WebSocket("ws://%s:%s/ws"); ),对请求的路由已经做了声明 % ( host, port ),在测试时编写websocket接口时记得不要改变路由‘/ws’,如果确实需要改变路由的话记得对于测试界面中初始化界面也需要做对应修改。当然,如果测试者采用一些测试接口软件的话,可不必考虑此部分。
完成上述编码后,逐次输入内容,可以得到与下图类似的测试界面接口。