使用Python創(chuàng)建websocket服務端并給出不同客戶端的請求
使用Python創(chuàng)建websocket服務端,并給出不同客戶端的請求

一、 WebSocket是啥
WebSocket 和HTTP一樣,也是一種通訊協(xié)議,允許服務端主動向客戶端推送數(shù)據(jù)。
在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。
有很多網(wǎng)站為了實現(xiàn)推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發(fā)出HTTP請求,然后由服務器返回最新的數(shù)據(jù)給客戶端的瀏覽器。這種傳統(tǒng)的模式帶來很明顯的缺點,即瀏覽器需要不斷的向服務器發(fā)出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數(shù)據(jù)可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。
HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務器資源和帶寬,并且能夠更實時地進行通訊。
二、 WebSocket的C/S架構(gòu)

在服務端啟動接收WebSocket請求的服務,客戶端建立Websocket連接并發(fā)送請求(Message),服務端接收后,就可以根據(jù)處理邏輯,按需向客戶端發(fā)送消息了,例如發(fā)送主動推送。
三、依賴的三方庫
Python websockets是用于在Python中構(gòu)建WebSocket服務器和客戶端的庫,它基于asyncio異步IO建立,提供基于協(xié)程的API。
請盡量使用Python≥3.6以上版本來運行websockets。
依賴的三方庫為: websocket, websocket-client.
pip install websocket pip3 install websocket-client pip3 install websockets
主要用到的API有:
websockets.connect() websockets.send() websockets.recv()
四、簡單例子
server.py,用于構(gòu)建websocket服務器,在本地8765端口啟動,會將接收到的消息加上I got your message:返回回去。
import asyncio
import websockets
async def echo(websocket, path):
async for message in websocket:
message = "I got your message: {}".format(message)
await websocket.send(message)
asyncio.get_event_loop().run_until_complete(websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()
client.py和指定url建立websocket連接,并發(fā)送消息,然后等待接收消息,并將消息打印出來。
import asyncio
import websockets
async def hello(uri):
async with websockets.connect(uri) as websocket:
await websocket.send("Hello world!")
recv_text = await websocket.recv()
print(recv_text)
asyncio.get_event_loop().run_until_complete(
hello('ws://localhost:8765'))
先執(zhí)行server.py,再執(zhí)行client.py,client.py的輸出結(jié)果如下:
I got your message: Hello world!
五 主動發(fā)消息
建立連接之后,客戶端可以隨時接收服務器發(fā)來的消息。服務器可以依據(jù)邏輯,給客戶端推送指定消息。
服務器和客戶端代碼會有一點變化,在服務器回完第一條消息之后,開始輪詢時間,當秒數(shù)達到0的時候,會主動給客戶端回一條消息。
server.py:
import asyncio
import websockets
import time
async def echo(websocket, path):
async for message in websocket:
message = "I got your message: {}".format(message)
await websocket.send(message)
while True:
t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if str(t).endswith("0"):
await websocket.send(t)
break
asyncio.get_event_loop().run_until_complete(
websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()
client.py:
import asyncio
import websockets
async def hello(uri):
async with websockets.connect(uri) as websocket:
await websocket.send("Hello world!")
print("< Hello world!")
while True:
recv_text = await websocket.recv()
print("> {}".format(recv_text))
asyncio.get_event_loop().run_until_complete(
hello('ws://localhost:8765'))
先執(zhí)行server.py,再執(zhí)行client.py,client.py的輸出結(jié)果如下:
< Hello world!
> I got your message: Hello world!
> 2020-05-29 15:11:50
最后一條消息則是服務端主動給客戶端發(fā)送的。
六、在瀏覽器上使用
如何在前端發(fā)送websocket請求呢?
看這段代碼,先建立連接,然后向服務端發(fā)送Hello world,然后把接收到的所有消息依次展示出來。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>websocket通信客戶端</title>
<script src="jquery-3.5.0.min.js"></script>
<script type="text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
// 打開一個 web socket
var ws = new WebSocket("ws://127.0.0.1:8765");
// 連接建立后的回調(diào)函數(shù)
ws.onopen = function () {
// Web Socket 已連接上,使用 send() 方法發(fā)送數(shù)據(jù)
ws.send("Hello world!");
$("#main").append("<p>" + "<=" + "Hello world!" + "</p>")
};
// 接收到服務器消息后的回調(diào)函數(shù)
ws.onmessage = function (evt) {
var received_msg = evt.data;
if (received_msg.indexOf("sorry") == -1) {
$("#main").append("<p>" + "=>" + received_msg + "</p>")
}
};
// 連接關閉后的回調(diào)函數(shù)
ws.onclose = function () {
// 關閉 websocket
alert("連接已關閉...");
};
} else {
// 瀏覽器不支持 WebSocket
alert("您的瀏覽器不支持 WebSocket!");
}
}
</script>
</head>
<body onload="WebSocketTest()">
<div id="main">
</div>
</body>
</html>效果大概的這樣的:

可以在一開始的時候就抓websocket的包:

這里可以清晰的看到每一條消息。
到此這篇關于使用Python創(chuàng)建websocket服務端并給出不同客戶端的請求的文章就介紹到這了,更多相關Python創(chuàng)建websocket服務端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
批標準化層 tf.keras.layers.Batchnormalization()解析
這篇文章主要介紹了批標準化層 tf.keras.layers.Batchnormalization(),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
使用Python通過oBIX協(xié)議訪問Niagara數(shù)據(jù)的示例
這篇文章主要介紹了使用Python通過oBIX協(xié)議訪問Niagara數(shù)據(jù)的示例,幫助大家更好的理解和學習python,感興趣的朋友可以了解下2020-12-12
Python中l(wèi)ogging.NullHandler 的使用教程
這篇文章主要介紹了Python中l(wèi)ogging.NullHandler 的使用教程,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下2018-11-11
Python內(nèi)置函數(shù)Type()函數(shù)一個有趣的用法
這篇文章主要介紹了Python內(nèi)置函數(shù)Type()函數(shù)一個有趣的用法,本文講解的是個人發(fā)現(xiàn)在的一個有趣的用法,注意這種寫法會導致代碼很難讀,需要的朋友可以參考下2015-02-02
django請求返回不同的類型圖片json,xml,html的實例
今天小編就為大家分享一篇django請求返回不同的類型圖片json,xml,html的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05

