websocket 的 REQ/RES 模式其實是不太健全的 API,今天我們會逐步調整實作,讓它越來越完整。同時昨天提到如何區分[RES1] 還是 [RES2] 的困擾也會在今天處理
async def handle_request(websocket, path):
async for request in websocket:
# 在這裡處理客戶端的請求
response = process_request(request)
# 將回應傳回客戶端
await websocket.send(response)
def process_request(request):
# 在這裡處理客戶端的請求,並返回回應
return "這是回應: " + request
start_server = websockets.serve(handle_request, "localhost", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
第一版,只能支援單支 API,所以我們需要再做一些擴充
需要稍微說明一下 async for request in websocket
這部分,它相當於連續不斷地呼叫 request = await websocket.recv()
這邊很像流水線,會有源源不絕地 request 要處理,而且這些 request 其實是不保證會按照時間順序送進來的
我們今天還沒有要處理不按順序的部分,關於這部分我們會再之後寫一篇文章討論
async def handle_request(websocket, path):
if path == "/api1":
async for request in websocket:
response = process_api1_request(request)
await websocket.send(response)
elif path == "/api2":
async for request in websocket:
response = process_api2_request(request)
await websocket.send(response)
else:
# 如果路徑不匹配任何已知的 API 端點,可以回應錯誤或採取其他操作
await websocket.send("未知的 API 端點")
def process_api1_request(request):
# 處理 API 1 的請求並返回回應
return "這是 API 1 的回應: " + request
def process_api2_request(request):
# 處理 API 2 的請求並返回回應
return "這是 API 2 的回應: " + request
# start_server 和其餘部分同 v1
上面是經過擴充的第二版,支援一個以上的 API,聰明的看倌們應該會發現 if path == "/apixxx"
判斷的部分看起來跟路由有 87 % 像,開始越來越有 API 的長相了。
但是等等,雖然我可以區分 REQ1 和 REQ2,可是如果連續呼叫 REQ1 兩次,這樣透過 path == "/apixxx"
仍舊還是沒辦法區分阿
這時候我們就要再增加一個 request_id 變量作區別了
async def handle_request(websocket, path):
async for request in websocket:
try:
# 解析收到的 JSON 請求
request_data = json.loads(request)
# 檢查請求是否包含請求 ID
if 'request_id' in request_data:
request_id = request_data['request_id']
response = None
# 根據路徑分派請求處理
if path == "/api1":
response = process_api1_request(request_data)
elif path == "/api2":
response = process_api2_request(request_data)
else:
response = {'error': '未知的 API 端點'}
# 將回應傳回客戶端,並使用請求 ID 進行識別
response_data = {'request_id': request_id, 'response': response}
await websocket.send(json.dumps(response_data))
else:
# 如果請求沒有請求 ID,則返回錯誤
error_response = {'error': '請求缺少請求 ID'}
await websocket.send(json.dumps(error_response))
except json.JSONDecodeError:
# 處理無效的 JSON 請求
error_response = {'error': '無效的 JSON 請求'}
await websocket.send(json.dumps(error_response))
# def process_api1_request(request) 以下部分同 v2
經過以上改動之後,我們就可以順利處理不同次呼叫的 REQ1 了
今天我們實作了 websocket 的 REQ/RES 模式,透過逐步加入新的機制,讓它越來越接近完整的 API
明天我們會再繼續探討 SUB/PUB 模式的 websocket 實作,敬請期待!