更新於 2024/01/29閱讀時間約 5 分鐘

【Python 軍火庫🧨 - websockets】雙向溝通的渠道

raw-image



我們在「【Web微知識系列】雙向溝通的技術,什麼是Websocket?」 有提到關於Websocket的概念, 他是一種網路傳輸的協定, 讓我們建立一次handshake的過程就可以相互傳遞資料, 而不用每次都重新進行Request請求, 進而耗費開啟/關閉連線的時間, 且省去了相互等待的依賴。

為什麼會說減少相互等待的過程呢? 因為Websocket的本質就是非同步的概念, 而關於非同步也歡迎參考「【Python - asyncio】非同步 I/O 簡介」, 它是一種我丟資料給你, 但你不一定馬上回報給我, 做完再回報給我即可的概念, 因此這中間的空檔就可以去完成其他的事物, 讓處理事情變得更有效率。

那就讓我們用實作來看看一個簡單的websocket究竟是怎麼運作的吧!

安裝套件

pip install websockets

Server端

功能: 我們的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端

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的訊息: 你好

有什麼特點?

  • 傳遞雙方約定好的資料格式,對於業務不清楚的攻擊者需要花費較多的時間來進行試誤, 但這就像把雙面刃, 接手的夥伴也較不容易上手, 尤其是特別複雜的應用。
  • 非同步讓我們不再傻傻的等待回應, 對於Client端來說能夠將時間分配到其他任務。
  • 容易實現即時應用。

結語

雙向溝通與非同步應用其實非常有趣, 主要在解決我們的即時性應用問題, 並且搭配非同步讓我們的運作更有效率, 就像是餐廳的服務員一樣, 將客戶帶位到目的後, 先請客戶看菜單, 而這段時間就能去服務其他客人, 不會單純的等待浪費時間,而websocket的部份則是讓我們傳輸過程中可以僅建立一次的連線, 基於這條連線不斷的傳輸資料, 尤其是串流的應用, 也省去的不斷三方交握的繁瑣程序。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.