中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

你真的了解WebSocket嗎?

發布時間:2020-07-19 11:43:12 來源:網絡 閱讀:1574 作者:python入門 欄目:開發技術

老男孩IT教育alex python教學總監教你認識WebSocket

 WebSocket協議是基于TCP的一種新的協議。WebSocket最初在HTML5規范中被引用為TCP連接,作為基于TCP的套接字API的占位符。它實現了瀏覽器與服務器全雙工(full-duplex)通信。其本質是保持TCP連接,在瀏覽器和服務端通過Socket進行通信。

 本文將使用Python編寫Socket服務端,一步一步分析請求過程!!!

1. 啟動服務端

1
2
3
4
5
6
7
8
9
10
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1'8002))
sock.listen(5)
# 等待用戶連接
conn, address = sock.accept()
...
...
...

啟動Socket服務器后,等待用戶【連接】,然后進行收發數據。

 

 

 

2. 客戶端連接

1
2
3
4
<script type="text/javascript">
    var socket = new WebSocket("ws://127.0.0.1:8002/xxoo");
    ...
</script>

 

 

當客戶端向服務端發送連接請求時,不僅連接還會發送【握手】信息,并等待服務端響應,至此連接才創建成功!

 

3. 建立連接【握手】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket
 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1'8002))
sock.listen(5)
# 獲取客戶端socket對象
conn, address = sock.accept()
# 獲取客戶端的【握手】信息
data = conn.recv(1024)
...
...
...
conn.send('響應【握手】信息')

 

 

 

 

 

 

 

       

請求和響應的【握手】信息需要遵循規則:


  • 從請求【握手】信息中提取 Sec-WebSocket-Key

  • 利用magic_string 和 Sec-WebSocket-Key 進行hmac1加密,再進行base64加密

  • 將加密結果響應給客戶端

注:magic string為:258EAFA5-E914-47DA-95CA-C5AB0DC85B11

請求【握手】信息為:

提取Sec-WebSocket-Key值并加密:

4.客戶端和服務端收發數據

客戶端和服務端傳輸數據時,需要對數據進行【封包】和【解包】。客戶端的JavaScript類庫已經封裝【封包】和【解包】過程,但Socket服務端需要手動實現。

第一步:獲取客戶端發送的數據【解包】

你真的了解WebSocket嗎? 基于Python實現解包過程(未實現長內容)

解包詳細過程: 

The MASK bit simply tells whether the message is encoded. Messages from the client must be masked, so your server should expect this to be 1. (In fact, section 5.1 of the spec says that your server must disconnect from a client if that client sends an unmasked message.) When sending a frame back to the client, do not mask it and do not set the mask bit. We'll explain masking later. Note: You have to mask messages even when using a secure socket.RSV1-3 can be ignored, they are for extensions.

The opcode field defines how to interpret the payload data: 0x0 for continuation, 0x1 for text (which is always encoded in UTF-8), 0x2 for binary, and other so-called "control codes" that will be discussed later. In this version of WebSockets, 0x3 to 0x7 and 0xB to 0xF have no meaning.

The FIN bit tells whether this is the last message in a series. If it's 0, then the server will keep listening for more parts of the message; otherwise, the server should consider the message delivered. More on this later.

Decoding Payload Length

To read the payload data, you must know when to stop reading. That's why the payload length is important to know. Unfortunately, this is somewhat complicated. To read it, follow these steps:

  1. Read bits 9-15 (inclusive) and interpret that as an unsigned integer. If it's 125 or less, then that's the length; you're done. If it's 126, go to step 2. If it's 127, go to step 3.

  2. Read the next 16 bits and interpret those as an unsigned integer. You're done.

  3. Read the next 64 bits and interpret those as an unsigned integer (The most significant bit MUST be 0). You're done.

Reading and Unmasking the Data

If the MASK bit was set (and it should be, for client-to-server messages), read the next 4 octets (32 bits); this is the masking key. Once the payload length and masking key is decoded, you can go ahead and read that number of bytes from the socket. Let's call the data ENCODED, and the key MASK. To get DECODED, loop through the octets (bytes a.k.a. characters for text data) of ENCODED and XOR the octet with the (i modulo 4)th octet of MASK. In pseudo-code (that happens to be valid JavaScript):

 

var DECODED = "";
for (var i = 0; i < ENCODED.length; i++) {
    DECODED[i] = ENCODED[i] ^ MASK[i % 4];
}

 

Now you can figure out what DECODED means depending on your application.

 第二步:向客戶端發送數據【封包】

你真的了解WebSocket嗎? View Code

5. 基于Python實現簡單示例

a. 基于Python socket實現的WebSocket服務端:

b. 利用JavaScript類庫實現客戶端

6. 基于Tornado框架實現Web聊天室

Tornado是一個支持WebSocket的優秀框架,其內部原理正如1~5步驟描述,當然Tornado內部封裝功能更加完整。

以下是基于Tornado實現的聊天室示例:

你真的了解WebSocket嗎? app.py

你真的了解WebSocket嗎? index.html

示例×××

 

 參考文獻:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers 

老男孩教育官網:www.oldboyedu.com


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黎城县| 房产| 竹溪县| 大邑县| 扶绥县| 新宁县| 杭锦旗| 阿克苏市| 始兴县| 汉沽区| 防城港市| 崇仁县| 克拉玛依市| 台江县| 珲春市| 拉萨市| 永年县| 霞浦县| 唐河县| 天柱县| 古浪县| 延安市| 宁强县| 垣曲县| 手机| 巩留县| 大渡口区| 公安县| 阳原县| 西畴县| 德格县| 句容市| 平遥县| 雷波县| 遂平县| 环江| 华容县| 武安市| 吴川市| 新沂市| 南木林县|