使用Python創(chuàng)建websocket服務(wù)端并給出不同客戶端的請(qǐng)求
使用Python創(chuàng)建websocket服務(wù)端,并給出不同客戶端的請(qǐng)求
一、 WebSocket是啥
WebSocket 和HTTP一樣,也是一種通訊協(xié)議,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。
在 WebSocket API 中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。
有很多網(wǎng)站為了實(shí)現(xiàn)推送技術(shù),所用的技術(shù)都是 Ajax 輪詢。輪詢是在特定的的時(shí)間間隔(如每1秒),由瀏覽器對(duì)服務(wù)器發(fā)出HTTP請(qǐng)求,然后由服務(wù)器返回最新的數(shù)據(jù)給客戶端的瀏覽器。這種傳統(tǒng)的模式帶來(lái)很明顯的缺點(diǎn),即瀏覽器需要不斷的向服務(wù)器發(fā)出請(qǐng)求,然而HTTP請(qǐng)求可能包含較長(zhǎng)的頭部,其中真正有效的數(shù)據(jù)可能只是很小的一部分,顯然這樣會(huì)浪費(fèi)很多的帶寬等資源。
HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時(shí)地進(jìn)行通訊。
二、 WebSocket的C/S架構(gòu)
在服務(wù)端啟動(dòng)接收WebSocket請(qǐng)求的服務(wù),客戶端建立Websocket連接并發(fā)送請(qǐng)求(Message),服務(wù)端接收后,就可以根據(jù)處理邏輯,按需向客戶端發(fā)送消息了,例如發(fā)送主動(dòng)推送。
三、依賴的三方庫(kù)
Python websockets是用于在Python中構(gòu)建WebSocket服務(wù)器和客戶端的庫(kù),它基于asyncio異步IO建立,提供基于協(xié)程的API。
請(qǐng)盡量使用Python≥3.6以上版本來(lái)運(yùn)行websockets。
依賴的三方庫(kù)為: websocket, websocket-client.
pip install websocket pip3 install websocket-client pip3 install websockets
主要用到的API有:
websockets.connect() websockets.send() websockets.recv()
四、簡(jiǎn)單例子
server.py
,用于構(gòu)建websocket服務(wù)器,在本地8765端口啟動(dòng),會(huì)將接收到的消息加上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ā)送消息,然后等待接收消息,并將消息打印出來(lái)。
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!
五 主動(dòng)發(fā)消息
建立連接之后,客戶端可以隨時(shí)接收服務(wù)器發(fā)來(lái)的消息。服務(wù)器可以依據(jù)邏輯,給客戶端推送指定消息。
服務(wù)器和客戶端代碼會(huì)有一點(diǎn)變化,在服務(wù)器回完第一條消息之后,開(kāi)始輪詢時(shí)間,當(dāng)秒數(shù)達(dá)到0的時(shí)候,會(huì)主動(dòng)給客戶端回一條消息。
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
最后一條消息則是服務(wù)端主動(dòng)給客戶端發(fā)送的。
六、在瀏覽器上使用
如何在前端發(fā)送websocket請(qǐng)求呢?
看這段代碼,先建立連接,然后向服務(wù)端發(fā)送Hello world,然后把接收到的所有消息依次展示出來(lái)。
<!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) { // 打開(kāi)一個(gè) 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>") }; // 接收到服務(wù)器消息后的回調(diào)函數(shù) ws.onmessage = function (evt) { var received_msg = evt.data; if (received_msg.indexOf("sorry") == -1) { $("#main").append("<p>" + "=>" + received_msg + "</p>") } }; // 連接關(guān)閉后的回調(diào)函數(shù) ws.onclose = function () { // 關(guān)閉 websocket alert("連接已關(guān)閉..."); }; } else { // 瀏覽器不支持 WebSocket alert("您的瀏覽器不支持 WebSocket!"); } } </script> </head> <body onload="WebSocketTest()"> <div id="main"> </div> </body> </html>
效果大概的這樣的:
可以在一開(kāi)始的時(shí)候就抓websocket的包:
這里可以清晰的看到每一條消息。
到此這篇關(guān)于使用Python創(chuàng)建websocket服務(wù)端并給出不同客戶端的請(qǐng)求的文章就介紹到這了,更多相關(guān)Python創(chuàng)建websocket服務(wù)端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python中使用websocket方法實(shí)例詳解
- 使用python構(gòu)建WebSocket客戶端的教程詳解
- python使用websocket庫(kù)發(fā)送WSS請(qǐng)求
- Python中使用dwebsocket實(shí)現(xiàn)后端數(shù)據(jù)實(shí)時(shí)刷新
- python開(kāi)發(fā)實(shí)例之python使用Websocket庫(kù)開(kāi)發(fā)簡(jiǎn)單聊天工具實(shí)例詳解(python+Websocket+JS)
- Python Websocket服務(wù)端通信的使用示例
- Python如何使用WebSocket實(shí)現(xiàn)實(shí)時(shí)Web應(yīng)用
相關(guān)文章
對(duì)pytorch中不定長(zhǎng)序列補(bǔ)齊的操作
這篇文章主要介紹了對(duì)pytorch中不定長(zhǎng)序列補(bǔ)齊的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05Django配置跨域并開(kāi)發(fā)測(cè)試接口
這篇文章主要介紹了Django配置跨域并開(kāi)發(fā)測(cè)試接口,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11批標(biāo)準(zhǔn)化層 tf.keras.layers.Batchnormalization()解析
這篇文章主要介紹了批標(biāo)準(zhǔn)化層 tf.keras.layers.Batchnormalization(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02使用Python通過(guò)oBIX協(xié)議訪問(wèn)Niagara數(shù)據(jù)的示例
這篇文章主要介紹了使用Python通過(guò)oBIX協(xié)議訪問(wèn)Niagara數(shù)據(jù)的示例,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-12-12Python中l(wèi)ogging.NullHandler 的使用教程
這篇文章主要介紹了Python中l(wèi)ogging.NullHandler 的使用教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-11-11Python內(nèi)置函數(shù)Type()函數(shù)一個(gè)有趣的用法
這篇文章主要介紹了Python內(nèi)置函數(shù)Type()函數(shù)一個(gè)有趣的用法,本文講解的是個(gè)人發(fā)現(xiàn)在的一個(gè)有趣的用法,注意這種寫(xiě)法會(huì)導(dǎo)致代碼很難讀,需要的朋友可以參考下2015-02-02Python實(shí)現(xiàn)調(diào)用攝像頭拍攝照片
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)調(diào)用攝像頭拍攝照片以及郵箱收集功能,文中的示例代碼講解詳細(xì),感興趣的可以動(dòng)手嘗試一下2022-06-06django請(qǐng)求返回不同的類(lèi)型圖片json,xml,html的實(shí)例
今天小編就為大家分享一篇django請(qǐng)求返回不同的類(lèi)型圖片json,xml,html的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05