Websockt概念
Websockt是一種網(wǎng)絡通信協(xié)議,允許客戶端和服務器雙向通信。最大的特點就是允許服務器主動推送數(shù)據(jù)給客戶端,比如股票數(shù)據(jù)在客戶端實時更新,就能利用websocket。
Websockt和http協(xié)議一樣,并不是設置在linux內(nèi)核中,而是通過用戶空間的應用程序來實現(xiàn)和處理。
http網(wǎng)址的格式:協(xié)議://域名/路徑。如:Example Domain。
websocket網(wǎng)址的格式:ws://域名/路徑 或 wss://域名/路徑。如:ws://www.example.com/chat。
Websocket與http的關聯(lián)
1、基于HTTP協(xié)議的握手:WebSocket協(xié)議的握手過程是基于HTTP協(xié)議的。在建立WebSocket連接之前,客戶端和服務器之間會進行一次HTTP握手,這是為了協(xié)商和確認使用WebSocket協(xié)議進行通信。
2、共享同一端口:WebSocket協(xié)議使用HTTP協(xié)議的80端口(或443端口,用于加密連接),這意味著WebSocket連接可以通過與HTTP服務器共享同一端口來進行通信。這樣可以避免在網(wǎng)絡上開啟新的端口,降低了網(wǎng)絡配置的復雜性。
Websocket與http對比
優(yōu)點
實時性:WebSocket支持雙向通信,服務器可以主動推送數(shù)據(jù)給客戶端,實現(xiàn)實時更新和推送功能。
較低的延遲:WebSocket建立一次連接后,可以保持長時間的連接狀態(tài),避免了每次請求都要建立新的連接的開銷,從而減少了延遲。
較小的數(shù)據(jù)開銷:WebSocket使用二進制消息傳輸,相對于HTTP的文本數(shù)據(jù)傳輸,可以減少數(shù)據(jù)包的大小,降低網(wǎng)絡傳輸開銷。
更少的網(wǎng)絡流量:由于WebSocket采用長連接,不需要頻繁的請求和響應,可以減少網(wǎng)絡流量和負載。
缺點
兼容性問題:WebSocket是HTML5的一部分,相對于HTTP,對于一些低版本的瀏覽器和服務器來說,支持程度可能較低。
需要服務器端支持:WebSocket需要服務器端支持實現(xiàn)雙向通信,而有些服務器可能沒有提供WebSocket的支持。
協(xié)議復雜性:相對于HTTP來說,WebSocket的協(xié)議相對復雜一些,實現(xiàn)和維護的成本可能較高。
Websocket的握手
與http握手的區(qū)別
下圖是websocket的握手報文案例。與http握手報文的核心區(qū)別是兩處紅框部分是否是Upgrade和websocket。
Websocket的握手流程
1.瀏覽器發(fā)送握手報文。
2.服務器解析出sec-websocket-key
3.sec-websocket-key與GUID字符串聯(lián)合成新字符串。
GUID是一組固定的字符串,在websocket的官方文檔里有規(guī)定。
4.用哈希算法對新字符串進行哈希
5.對哈希值轉(zhuǎn)為base64格式,生成value
6.把value配握手返回報文中進行返回
仿股票數(shù)據(jù)推流
股票數(shù)據(jù)的推流的特點:客戶端連接上服務器之后,服務器就會定時往客戶端發(fā)送更新過的股票數(shù)據(jù)。
下圖實現(xiàn)了一個簡易版的服務器,能定時給連接上的客戶端推送數(shù)據(jù),當客戶端嘗試發(fā)送數(shù)據(jù)的時候會斷開連接。
import asyncio
import websockets
async def push_price(websocket, path):
while True:
price = "price = 299.9"
await websocket.send(price)
try:
# 接收消息
message = await asyncio.wait_for(websocket.recv(), timeout=1)
# 如果接收到消息,立即斷開連接
if message:
await websocket.close()
break
except:
pass
start_server = websockets.serve(push_price, None, 8765) //返回一個協(xié)程對象
//該對象的任務函數(shù)是push_price
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
客戶端
<html>
<head>
<script>
let ws;
function doConnect(addr) {
ws = new WebSocket("ws://" + addr);
ws.onopen = () => {
document.getElementById("log").value += (" Connection opened\n");
};
ws.onmessage = (event) => {
document.getElementById("log").value += (" Receive: " + event.data + "\n\n"); // JSON.stringify()
};
ws.onclose = () => {
document.getElementById("log").value += (" Connection closed\n");
};
}
document.addEventListener("DOMContentLoaded", (event) => {
document.getElementById("btn_connect").onclick = () => {
let server_addr = document.getElementById("server_addr").value;
doConnect(server_addr);
};
document.getElementById("btn_send").onclick = () => {
let msg = document.getElementById("message").value;
ws.send(msg);
document.getElementById("log").value += (" Send: " + msg + "\n");
};
});
</script>
</head>
<body>
<div id="header">
<h1 align="left">WebSocket Client</h1>
Server: <input id="server_addr" type="text" value="192.168.232.132:8888">
<input id="btn_connect" type="button" value="Connect!"><br/><br/>
Message: <input id="message" type="text" value="">
<input id="btn_send" type="button" value="Send"><br/><br/>
<textarea cols="250" id="log" rows="50"></textarea>
</div>
</body>
</html>
~
~
~
運行結(jié)果文章來源:http://www.zghlxwxcb.cn/news/detail-822325.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-822325.html
到了這里,關于websocket介紹并模擬股票數(shù)據(jù)推流的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!