日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WebSocket小叙

發(fā)布時間:2024/8/23 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebSocket小叙 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

剛看到WeSocket的時候,我以為是HTTP相關,但是在前兩天搭了一個簡單的Client之后, 我發(fā)現這不就是TCP長連接么? 建立連接->通信->斷開連接. 直到今天, 我在調試的時候, 發(fā)現發(fā)出了HTTP請求, 我想, 事情可能不是我想的那樣.

先來簡單描述一下當時的情況

我用Python代碼簡單打了一個WebSocket 客戶端, 想著試一試, 代碼很簡單, 就是這:

import websocket import threading import timeclass Status:INIT = 'init'OPENED = 'opened'CLOSED = 'closed'class WSTest:def __init__(self):self.thread = Noneself.ping_thread = Noneself.ws = Noneself.status = Status.INITdef send_message(self, message) -> bool:if self.status != Status.OPENED:return Falseself.ws.send(message)return Truedef close(self):self.ws.close()# 等待關閉for i in range(200):time.sleep(0.02)if self.status == Status.CLOSED:breakif self.status != Status.CLOSED:returnif self.ping_thread and self.ping_thread.is_alive():self.ping_thread.join()def run(self):def on_message(ws, message):print(message)def on_error(ws, error):print(error)def on_close(ws):print('關閉連接')self.status = Status.CLOSEDdef on_open(ws):self.status = Status.OPENEDself.ws = websocket.WebSocketApp("ws://echo.websocket.org",on_open=on_open,on_message=on_message,on_close=on_close,on_error=on_error)self.ping_thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 2, 5))self.ping_thread.start()if __name__ == "__main__":ws = WSTest()ws.run()while True:s = input()if s == 'close':breakws.send_message(s)ws.close()

上面的ws://echo.websocket.org 是一個測試用的域名,你發(fā)送什么過去,他就會返回什么. 到這里我簡單運行了一下,還可以.本來我想簡單搭一個,能調通就得了唄,但是,手賤的我打開了wireshark. 我想看一下它的網絡連接.

wireshark抓包查看

首先,找到域名的IP

找到IP后就可以直接對IP進行過濾,找到接收和發(fā)送的數據包.直接過濾所有DNS解析請求,查找指定域名.

然后,針對地址對請求進行過濾

來來來,看到了什么?前面三個TCP請求是三次握手的請求,在三次握手之后的第一個請求是什么,HTTP???

看一下它的請求內容:

看到第一個Upgrade之后,我仿佛懂了.這個字段的含義是要將協(xié)議升級.后面跟著的就是websocket了,再看一下服務器的response.(后面那個TCP請求可以跳過,就是服務器告訴你它收到了).

響應內容雖然有不明白的地方,但是大概看來,是同意升級協(xié)議的意思了.再然后才是websocket通信內容,以及最后的揮手告別.

也就是說,websocket雖然能夠實現雙向通信,但是它的連接建立是從HTTP開始,然后升級協(xié)議來的??

所以websocket的通信流程是:

  • 三次握手建立TCP通信
  • 發(fā)起HTTP請求,升級為websokcet協(xié)議
  • 開始websocket通信
  • 斷開連接
  • 如果把中間的websocket去掉,那就完全是HTTP協(xié)議了. 沒想到websocket與HTTP是兄弟倆.

    思考

    既然WebSocket是基于HTTP協(xié)議建立的, 那么他的出現就一定是在HTTP之后, 這就說明它一定是為了解決HTTP的某些問題而出現的. 很顯然: HTTP的單向通信限制, 服務器不能主動聯(lián)系客戶端

    HTTP協(xié)議本身就是基于TCP的, 而TCP本身就是全雙工通信的. 這感覺就像是他們借用了一下HTTP, 然后說咱們接下來就都用WebSocket吧.

    那么問題來了, 既然要實現這種長連接, 為什么還要借助HTTP之手, 直接TCP建立連接不行么? 查了一下, 發(fā)現是為了兼容. 因為WebSocket就是為了解決HTTP協(xié)議問題, 也就是說主要運行在之前HTTP的場景中, 而為了兼容現有瀏覽器的握手規(guī)范, 所以借助了HTTP協(xié)議來完成握手.

    WebSocket協(xié)議是: ws 和 wss. 其區(qū)別與 http 和 https 相同. wss 就是在 ws 的通信過程中再套一層TLS/SSL 協(xié)議.

    那么WebSocket有哪些應用場景呢?

    可以這么說, 在原來使用HTTP協(xié)議進行輪訓的場景, 都可以使用WebSocket替換.

    • 在線聊天
    • 直播
    • 在線多人游戲
    • 等等…

    最后, 記一下建立連接的HTTP請求的頭信息

    request

    • connection: Upgrade 升級協(xié)議
    • Upgrade: websocket 指定升級為WebSocket協(xié)議
    • Sec-WebSocket-Key: 用于判斷客戶端是否有權升級協(xié)議
    • Sec-WebSocket-Version:指定WebSocket 版本

    response

    • Upgrade: websocket 成功升級協(xié)議
    • Sec-WebSocket-Accept: 通過Sec-WebSocket-Key計算得來

    總結

    以上是生活随笔為你收集整理的WebSocket小叙的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。