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 實作,敬請期待!