原理: 利用ajax定時朝後端傳送請求,比如每隔五秒鐘發一次請求,那麼你的資料延遲就可能會高達五秒
特點: 資料延遲,消耗資源過大,請求次數太多
原理: 利用ajax + 佇列 定時朝後端傳送請求, 如果沒有資料則會阻塞但是不會一直阻塞, 比如阻塞你30秒,還沒有資料則返回,然後讓客戶端瀏覽器再次傳送請求資料的請求
特點: 相對於輪詢基本是沒有訊息延遲的,請求次數降低了很多
websocket 的最大特點就是,瀏覽器與服務端建立鏈結之後預設不再斷開,伺服器可以主動向客戶端推送資訊,客戶端也可以主動向伺服器傳送資訊
第一次訪問服務端的時候(基於http協議) 瀏覽器會自動生成乙個隨機字串放在請求頭中帶給服務端然後自己也保留乙份
sec-websocket-key: epw8kp1xqlnwbjxe/q38sa==
服務端和客戶端都對隨機字串做下面的操作:
1.隨機字串 + magic string拼接
2.然後再將拼接好的結果進行加密處理(sha1/base64)的到密文
服務端將產生的密文通過響應頭再次傳送給客戶端瀏覽器進行對比,假設比對上了 建立websocket鏈結 基於該鏈結收發訊息
由於websocket是加密傳輸資料的,基於網路傳輸的資料都是二進位制格式 對應到我們python中就是bytes型別
進行如下解密:
1.先讀取第2個位元組後7位(payload) 針對後七位的位數做不同的處理機制
=127:再往後讀取8個位元組
=126:再往後讀取2個位元組
<=125:不再往後讀取
基於上述操作之後 所有的情況都繼續往後讀取4個位元組(masking-key),基於該masking-key依據解密公式解密出真實資料
前端關鍵**
// 上述**做的事
// 1.自動生產隨機字串並傳送給服務端
// 2.自動對隨機字串繼續一系列操作 magic string 加密
// 3.自動對比服務端加密字串、
不是所有的服務端都支援websocket,
django 預設不支援,只支援http協議
flask 預設不支援
tronado 預設支援
在django中如果想要基於websocket開發專案 你需要安裝模組:channles
pip3 install channels==2.3
注意:版本不要使用最新的,如果安裝最新的可能會自動把你的django版本公升級到最新版
對應的直譯器環境建議使用3.6
channels模組內部已經幫我們封裝好了 握手/加密/解密的工作
1.需要在配置檔案settings.py中註冊channles應用
...# 1.需要先註冊channels
'channels']
2.還需要在配置檔案settings.py中配置以下引數
# 這裡的channels_demo是專案名
3.在專案資料夾下建立routing.py檔案,檔案內寫一下內容
from channels.routing import protocoltyperouter,urlrouter
'websocket':urlrouter([
# 路由與檢視函式對應關係
url(r'^chat/',consumers.chatconsumer)
# consumers是處理websocket請求的視**件
# chatconsumer是檢視類
])})
上述配置完成後,啟動django專案會發現
django由原來預設的wsgiref啟動變成asgi啟動
注意配置完成後,django就會即支援http協議也支援websocket協議
相容http協議原始碼:
正常的http協議還是按照之前的寫法 在urls中寫路由與檢視函式對應關係
而針對websocket協議則在當前檔案內書寫路由與檢視函式對應關係
4.在視**件consumer.py中書寫websocket請求的邏輯
from channels.generic.websocket import websocketconsumer
class chatconsumer(websocketconsumer):
def websocket_connect(self, message):
"""客戶端發來鏈結請求之後就會自動觸發
"""def websocket_receive(self, message):
"""客戶端向服務端傳送訊息就會自動觸發
"""def websocket_disconnect(self, message):
"""客戶端主動斷開鏈結之後自動觸發
"""
前端**
後端**
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 預設只支援http協議
url(r'^index/',views.index)
]
def index(request):
return render(request,'index.html')
'websocket':urlrouter([
url(r'^chat/',consumers.chatconsumer)
])})
rom channels.generic.websocket import websocketconsumer
from channels.exceptions import stopconsumer
consumer_object_list =
class chatconsumer(websocketconsumer):
def websocket_connect(self, message):
"""客戶端發來鏈結請求之後就會自動觸發
:param message:
:return:
"""# print('驗證')
self.accept() # 向服務端傳送加密字串
# self就是每乙個客戶端物件
# 鏈結成功 我就將當前物件放入全域性的列表中
def websocket_receive(self, message):
"""客戶端向服務端傳送訊息就會自動觸發
:param message:內部包含客戶端給你傳送的訊息
:return:
"""print(message)
# 給客戶端回訊息
# self.send(text_data=message.get('text'))
# 給列表中所有的物件都傳送訊息
for obj in consumer_object_list:
obj.send(text_data=message.get('text'))
def websocket_disconnect(self, message):
"""客戶端主動斷開鏈結之後自動觸發
:param message:
:return:
"""print('斷開鏈結了')
# 服務端斷開鏈結 就去列表中刪除對應的客戶端物件
consumer_object_list.remove(self)
raise stopconsumer
前端四個方法
var ws = new websocket('ws:');
ws.onopen
ws.send()
ws.onmessage
ws.close()
後端三個方法
websocket_connect
websocket_receive
websocket_disconnect
輪詢,長輪詢,websocket原理
讓瀏覽器定時朝後端傳送請求 通過ajax向後端偷偷傳送資料 比如每隔五秒鐘發一次請求,那麼你的資料延遲就可能會高達五秒 不足之處 資料延遲 消耗資源過大 請求次數太多 佇列 ajax 服務端給每個客戶端建立佇列,讓瀏覽器通過ajax朝服務端要資料,去各自的佇列中獲取 如果沒有資料則會阻塞但是不會一直...
1 輪詢 長輪詢 websocket簡介
一 輪詢 前端每隔固定時間向後台傳送一次請求,詢問伺服器是否有新資料 缺點 延遲,需要固定的輪詢時間,不一定是實時資料 大量耗費伺服器記憶體和寬頻資源,因為不停的請求伺服器,很多時候 並沒有新的資料更新,因此絕大部分請求都是無效請求 二 長輪詢 當伺服器收到前端發來的請求後,伺服器端不會直接進行響應...
輪詢 長輪詢
輪詢 通過setinterval向後台請求資料,更新html from flask import flask,render template,request,jsonify users 2 3 user list defuser list import time return render temp...