我們在「【Web微知識系列】雙向溝通的技術,什麼是Websocket?」 有提到關於Websocket的概念, 他是一種網路傳輸的協定, 讓我們建立一次handshake的過程就可以相互傳遞資料, 而不用每次都重新進行Request請求, 進而耗費開啟/關閉連線的時間, 且省去了相互等待的依賴。
為什麼會說減少相互等待的過程呢? 因為Websocket的本質就是非同步的概念, 而關於非同步也歡迎參考「【Python - asyncio】非同步 I/O 簡介」, 它是一種我丟資料給你, 但你不一定馬上回報給我, 做完再回報給我即可的概念, 因此這中間的空檔就可以去完成其他的事物, 讓處理事情變得更有效率。
那就讓我們用實作來看看一個簡單的websocket究竟是怎麼運作的吧!
pip install websockets
功能: 我們的Server端會接收來自Client的訊息並回應「已經收到了」。
有沒有發現, 幾乎函式都與async、await離不開關係, 所以真心建議好好研讀「【Python - asyncio】非同步 I/O 簡介」才能夠更加得心應手。
import asyncio
import websockets
async def server(websocket, path):
while True:
try:
message = await websocket.recv()
await websocket.send(f"已收到來自Client的訊息: {message}")
except websockets.exceptions.ConnectionClosedOK:
print("Client disconnected")
break
async def main():
async with websockets.serve(server, "127.0.0.1", 8766):
print('start server: 127.0.0.1:8766')
await asyncio.Future() # run forever
asyncio.run(main())
啟動後就是不斷的等待Client端的連線, 而server函式裡就是我們進行訊息溝通的相關處理。
python server.py
start server: 127.0.0.1:8766
Client端的部份主要讓使用者輸入文字, 並將文字傳送到伺服端, 而收到伺服端的訊息之後印出於終端機。
import asyncio
import websockets
async def client():
async with websockets.connect("ws://127.0.0.1:8766") as websocket:
while True:
message = input("請輸入訊息 (type 'exit' to quit): ")
await websocket.send(message)
if message.lower() == "exit":
break
response = await websocket.recv()
print(f"來自Server的訊息: {response}")
asyncio.run(client())
使用的過程如下:
python client.py
請輸入訊息 (type 'exit' to quit): 你好
來自Server的訊息: 已收到來自Client的訊息: 你好
雙向溝通與非同步應用其實非常有趣, 主要在解決我們的即時性應用問題, 並且搭配非同步讓我們的運作更有效率, 就像是餐廳的服務員一樣, 將客戶帶位到目的後, 先請客戶看菜單, 而這段時間就能去服務其他客人, 不會單純的等待浪費時間,而websocket的部份則是讓我們傳輸過程中可以僅建立一次的連線, 基於這條連線不斷的傳輸資料, 尤其是串流的應用, 也省去的不斷三方交握的繁瑣程序。