9. 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP2改造篇之HPACK示例, 瞭解http2頭信息如何處理

来源:https://www.cnblogs.com/luojiawaf/archive/2023/10/09/17750621.html
-Advertisement-
Play Games

9. 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP2改造篇之HPACK示例, 瞭解http2頭信息如何處理 項目 ++wmproxy++ gite: https://gitee.com/tickbh/wmproxy github: https://github.com/ti ...


9. 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP2改造篇之HPACK示例, 瞭解http2頭信息如何處理

項目 ++wmproxy++

gite: https://gitee.com/tickbh/wmproxy

github: https://github.com/tickbh/wmproxy

關於HPACK相關數據的示例

長度編碼的示例,用5位的首碼示例

  • 將10進行編碼,10小於2^5-1,故
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| X | X | X | 0 | 1 | 0 | 1 | 0 |   10 stored on 5 bits
+---+---+---+---+---+---+---+---+
  • 將1337進行編碼
  1. 1337大於2^5-1,故前5位填充
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| X | X | X | 1 | 1 | 1 | 1 | 1 |  31
+---+---+---+---+---+---+---+---+
  1. 1337 - 31 = 1306,大於128,故需要二次填充,用1306 mod 128 = 21,首位填充1,故8位填充為,當前偏移值為7
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |  26
+---+---+---+---+---+---+---+---+
  1. 對1301-21=1280,1280 / 128 = 10, 10 < 128,故已經完成,首位填0
  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |  10
+---+---+---+---+---+---+---+---+

最終的填充值:

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| X | X | X | 1 | 1 | 1 | 1 | 1 |  Prefix = 31, I = 1306
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |  1306>=128, encode(154), I=1306/128
| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |  10<128, encode(10), done
+---+---+---+---+---+---+---+---+

頭部編碼示例

在靜態列表中索引

以下待索引的值

:method: GET

十六進位表示值82,二進位表示10000010,表示取靜態表2的值,查表為(:method, GET)

不在列表中,但請求索引,未使用HUFFMAN

以下示例

custom-key: custom-header

十六進位表示

400a 6375 7374 6f6d 2d6b 6579 0d63 7573 | @.custom-key.cus
746f 6d2d 6865 6164 6572                | tom-header

解碼過程

40                                      | == 01開頭請求索引 ==
0a                                      |   name (長度 10)
6375 7374 6f6d 2d6b 6579                | custom-key
0d                                      |   value (長度 13)
6375 7374 6f6d 2d68 6561 6465 72        | custom-header
                                        | -> custom-key:
                                        |   custom-header

動態表 (解碼之後):

[ 1] (占用 55) custom-key: custom-header
占用長度: 10+13+32=55

名字在列表中,但不索引,未使用HUFFMAN

以下示例

:path: /sample/path

十六進位表示

040c 2f73 616d 706c 652f 7061 7468      | ../sample/path

解碼過程

04                                      | == 0000開頭,請求不索引 ==
                                        |   name從索引取 (idx = 4)
                                        |   值為:path
0c                                      |   value (長度12)
2f73 616d 706c 652f 7061 7468           | /sample/path
                                        | -> :path: /sample/path

永不索引,未使用HUFFMAN

以下示例

password: secret

十六進位表示

1008 7061 7373 776f 7264 0673 6563 7265 | ..password.secre
74                                      | t

解碼過程

10                                      | == 0001開頭不索引 ==
08                                      |   name (長度8)
7061 7373 776f 7264                     | password
06                                      |   value (長度6)
7365 6372 6574                          | secret
                                        | -> password: secret

完整的請求示例,不使用HUFFMAN

以下幾個示例將連接請求,後續的會用到前面的動態列表

第一次請求. 示例如下

:method: GET
:scheme: http
:path: /
:authority: www.example.com

十六進位表示

8286 8441 0f77 7777 2e65 7861 6d70 6c65 | ...A.www.example
2e63 6f6d                               | .com

解碼過程


82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - 靜態表 ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - 靜態表 ==
                                        |   idx = 4
                                        | -> :path: /
41                                      | == 01開頭請求索引 indexed ==
                                        |   Indexed name (idx = 1)
                                        |     :authority
0f                                      |   Literal value (長度15)
7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
                                        | -> :authority: 
                                        |   www.example.com

動態列表 (解碼後):

[ 1->62] (s = 57) :authority: www.example.com
列表長度: 57

第二次請求. 示例如下,新加了cache-control欄位,其它和第一次一樣

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

十六進位表示

8286 84be 5808 6e6f 2d63 6163 6865      | ....X.no-cache

解碼過程

82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - 靜態表 ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - 靜態表 ==
                                        |   idx = 4
                                        | -> :path: /
be                                      | == Indexed - 動態表,索引值62及以上的為動態表 ==
                                        |   idx = 62
                                        | -> :authority:
                                        |   www.example.com
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
08                                      |   Literal value (8)
6e6f 2d63 6163 6865                     | no-cache
                                        | -> cache-control: no-cache

動態列表 (解碼後):

[ 1->62] (s = 53) cache-control: no-cache
[ 2->63] (s = 57) :authority: www.example.com
總長度: 110

第三次請求. 示例如下

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

十六進位表示

8287 85bf 400a 6375 7374 6f6d 2d6b 6579 | [email protected]
0c63 7573 746f 6d2d 7661 6c75 65        | .custom-value

解碼過程

82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
87                                      | == Indexed - 靜態表 ==
                                        |   idx = 7
                                        | -> :scheme: https
85                                      | == Indexed - 靜態表 ==
                                        |   idx = 5
                                        | -> :path: /index.html
bf                                      | == Indexed - 動態表 ==
                                        |   idx = 63
                                        | -> :authority:
                                        |   www.example.com
40                                      | == Literal indexed ==
0a                                      |   Literal name (長度10)
6375 7374 6f6d 2d6b 6579                | custom-key
0c                                      |   Literal value (長度12)
6375 7374 6f6d 2d76 616c 7565           | custom-value
                                        | -> custom-key:
                                        |   custom-value

動態列表 (解碼後):

[ 1->62] (s = 54) custom-key: custom-value
[ 2->63] (s = 53) cache-control: no-cache
[ 3->64] (s = 57) :authority: www.example.com
總長度: 164

完整的請求示例(和上述例子一模一樣,但是使用HUFFMAN)

以下幾個示例將連接請求,後續的會用到前面的動態列表

第一次請求. 示例如下

:method: GET
:scheme: http
:path: /
:authority: www.example.com

十六進位表示

8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 | ...A......:k....
ff                                      | .

比之前少了3位元組

解碼過程

82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - 靜態表 ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - 靜態表 ==
                                        |   idx = 4
                                        | -> :path: /
41                                      | == Literal indexed ==
                                        |   Indexed name (idx = 1)
                                        |     :authority
8c                                      |   Literal value (長度12)
                                        |     Huffman encoded:
f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
                                        |     Decoded:
                                        | www.example.com
                                        | -> :authority:
                                        |   www.example.com

動態列表 (解碼後):

[  1->62] (s =  57) :authority: www.example.com
      列表長度:  57

第二次請求. 示例如下,新加了cache-control欄位,其它和第一次一樣

:method: GET
:scheme: http
:path: /
:authority: www.example.com
cache-control: no-cache

十六進位表示

8286 84be 5886 a8eb 1064 9cbf           | ....X....d..

比之前少了2位元組

解碼過程

82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
86                                      | == Indexed - 靜態表 ==
                                        |   idx = 6
                                        | -> :scheme: http
84                                      | == Indexed - 靜態表 ==
                                        |   idx = 4
                                        | -> :path: /
be                                      | == Indexed - 動態表 ==
                                        |   idx = 62
                                        | -> :authority:
                                        |   www.example.com
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
86                                      |   Literal value (長度6)
                                        |     Huffman encoded:
a8eb 1064 9cbf                          | ...d..
                                        |     Decoded:
                                        | no-cache
                                        | -> cache-control: no-cache

動態列表 (解碼後):

[  1->62] (s =  53) cache-control: no-cache
[  2->63] (s =  57) :authority: www.example.com
      列表長度: 110

第三次請求. 示例如下

:method: GET
:scheme: https
:path: /index.html
:authority: www.example.com
custom-key: custom-value

十六進位表示

8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 | ....@.%.I.[.}..%
a849 e95b b8e8 b4bf                     | .I.[....

比之前少了5位元組

解碼過程

82                                      | == Indexed - 靜態表 ==
                                        |   idx = 2
                                        | -> :method: GET
87                                      | == Indexed - 靜態表 ==
                                        |   idx = 7
                                        | -> :scheme: https
85                                      | == Indexed - 靜態表 ==
                                        |   idx = 5
                                        | -> :path: /index.html
bf                                      | == Indexed - 動態表 ==
                                        |   idx = 63
                                        | -> :authority:
                                        |   www.example.com
40                                      | == Literal indexed ==
88                                      |   Literal name (長度8)
                                        |     Huffman encoded:
25a8 49e9 5ba9 7d7f                     | %.I.[.}.
                                        |     Decoded:
                                        | custom-key
89                                      |   Literal value (長度9)
                                        |     Huffman encoded:
25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
                                        |     Decoded:
                                        | custom-value
                                        | -> custom-key:
                                        |   custom-value

動態列表 (解碼後):

[  1->62] (s =  54) custom-key: custom-value
[  2->63] (s =  53) cache-control: no-cache
[  3->64] (s =  57) :authority: www.example.com
      總長度: 164

HUFFMAN編碼在於首次如果數據較大的時候優勢會更加明顯,如果數據較小,或者在後續的時候與普通編碼命中索引時基本一致。

完整的返回示例(HUFFMAN)

HUFFMAN與普通的差別在於字元串編解碼時的差別,這裡只介紹一種,並且設置SETTINGS_HEADER_TABLE_SIZE為256

以下幾個示例將連接請求,後續的會用到前面的動態列表

第一次返回. 示例如下

:status: 302
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

十六進位表示

4882 6402 5885 aec3 771a 4b61 96d0 7abe | H.d.X...w.Ka..z.
9410 54d4 44a8 2005 9504 0b81 66e0 82a6 | ..T.D. .....f...
2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8 | -..n..)...c.....
e9ae 82ae 43d3                          | ....C.

解碼過程


48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
82                                      |   Literal value (長度2)
                                        |     Huffman encoded:
6402                                    | d.
                                        |     Decoded:
                                        | 302
                                        | -> :status: 302
58                                      | == Literal indexed ==
                                        |   Indexed name (idx = 24)
                                        |     cache-control
85                                      |   Literal value (長度5)
                                        |     Huffman encoded:
aec3 771a 4b                            | ..w.K
                                        |     Decoded:
                                        | private
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
96                                      |   Literal value (長度22)
                                        |     Huffman encoded:
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
e082 a62d 1bff                          | ...-..
                                        |     Decoded:
                                        | Mon, 21 Oct 2013 20:13:21
                                        | GMT
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
6e                                      | == Literal indexed ==
                                        |   Indexed name (idx = 46)
                                        |     location
91                                      |   Literal value (長度17)
                                        |     Huffman encoded:
9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C
d3                                      | .
                                        |     Decoded:
                                        | https://www.example.com
                                        | -> location:
                                        |   https://www.example.com

動態列表 (解碼後):

[  1->62] (s =  63) location: https://www.example.com
[  2->63] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  3->64] (s =  52) cache-control: private
[  4->65] (s =  42) :status: 302
      Table size: 222

第二次請求. 示例如下,只是狀態碼發生了變更

:status: 307
cache-control: private
date: Mon, 21 Oct 2013 20:13:21 GMT
location: https://www.example.com

十六進位表示

4883 640e ffc1 c0bf                     | H.d.....

解碼過程


48                                      | == Literal indexed ==
                                        |   Indexed name (idx = 8)
                                        |     :status
83                                      |   Literal value (長度3)
                                        |     Huffman encoded:
640e ff                                 | d..
                                        |     Decoded:
                                        | 307
                                        | - evict: :status: 302
                                        | -> :status: 307
c1                                      | == Indexed - Add ==
                                        |   idx = 65
                                        | -> cache-control: private
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> date: Mon, 21 Oct 2013
                                        |   20:13:21 GMT
bf                                      | == Indexed - Add ==
                                        |   idx = 63
                                        | -> location:
                                        |   https://www.example.com

動態列表 (解碼後):

[  1->62] (s =  42) :status: 307
[  2->63] (s =  63) location: https://www.example.com
[  3->64] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
[  4->65] (s =  52) cache-control: private
      Table size: 222

由於(:status, 302)的長度為42,且42+222=264>256,所以捨棄最大值

第三次請求. 示例如下

:status: 200
cache-control: private
date: Mon, 21 Oct 2013 20:13:22 GMT
location: https://www.example.com
content-encoding: gzip
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1

十六進位表示

88c1 6196 d07a be94 1054 d444 a820 0595 | ..a..z...T.D. ..
040b 8166 e084 a62d 1bff c05a 839b d9ab | ...f...-...Z....
77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b | w..........5...[
3960 d5af 2708 7f36 72c1 ab27 0fb5 291f | 9`..'..6r..'..).
9587 3160 65c0 03ed 4ee5 b106 3d50 07   | ..1`e...N...=P.

比之前少了5位元組

解碼過程


88                                      | == Indexed - 靜態表 ==
                                        |   idx = 8
                                        | -> :status: 200
c1                                      | == Indexed - 動態表 ==
                                        |   idx = 65
                                        | -> cache-control: private
61                                      | == Literal indexed ==
                                        |   Indexed name (idx = 33)
                                        |     date
96                                      |   Literal value (長度22)
                                        |     Huffman encoded:
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
e084 a62d 1bff                          | ...-..
                                        |     Decoded:
                                        | Mon, 21 Oct 2013 20:13:22
                                        | GMT
                                        | - evict: cache-control:
                                        |   private
                                        | -> date: Mon, 21 Oct 2013 
                                        |   20:13:22 GMT
c0                                      | == Indexed - Add ==
                                        |   idx = 64
                                        | -> location:
                                        |   https://www.example.com
5a                                      | == Literal indexed ==
                                        |   Indexed name (idx = 26)
                                        |     content-encoding
83                                      |   Literal value (長度3)
                                        |     Huffman encoded:
9bd9 ab                                 | ...
                                        |     Decoded:
                                        | gzip
                                        | - evict: date: Mon, 21 Oct
                                        |    2013 20:13:21 GMT
                                        | -> content-encoding: gzip
77                                      | == Literal indexed ==
                                        |   Indexed name (idx = 55)
                                        |     set-cookie
ad                                      |   Literal value (長度45)
                                        |     Huffman encoded:
94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9`
d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)...
3160 65c0 03ed 4ee5 b106 3d50 07        | 1`e...N...=P.
                                        |     Decoded:
                                        | foo=ASDJKHQKBZXOQWEOPIUAXQ
                                        | WEOIU; max-age=3600; versi
                                        | on=1
                                        | - evict: location:
                                        |   https://www.example.com
                                        | - evict: :status: 307
                                        | -> set-cookie: foo=ASDJKHQ
                                        |   KBZXOQWEOPIUAXQWEOIU; ma
                                        |   x-age=3600; version=1

動態列表 (解碼後):

[  1->62] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
                 max-age=3600; version=1
[  2->63] (s =  52) content-encoding: gzip
[  3->64] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
總長度: 215

動態列表保留著一個最大的緩存大小值,每一個鍵值對的計算為name的位元組數+value的位元組數+32為確定的大小值。超出大小部分則丟棄不緩存,預設大小為4096。

總結

HPACK管理著HTTP2的頭部的協議部分,有著高壓縮比和重覆請求的高復用性,雙方編碼解碼需要各自維持一份動態表,動態根據處理數據來動態拓展,保證雙方維持的表一模一樣。從而保證ID索引不會亂。Huffman編碼把頭裡面需要用到字元串的數據進行進一步的壓縮,相對來說整個過程複雜度比HTTP1高很多,但相對的對使用者完全透明,在不影響其使用的情況下提高傳輸效率,並減少帶寬的使用量。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在本篇文章中,我們深入探討了Go語言中字元串的魅力和深度。從基礎定義、操作、字元編碼到複雜的類型轉換,每個環節都帶有實例和代碼示例來深化理解。通過這些深入的解析,讀者不僅能夠掌握字元串在Go中的核心概念,還能洞察Go設計哲學背後的思考。 關註公眾號【TechLeadCloud】,分享互聯網架構、雲服 ...
  • 歡迎訪問我的GitHub 這裡分類和彙總了欣宸的全部原創(含配套源碼):https://github.com/zq2599/blog_demos 時隔兩年,《client-go實戰》被激活,更多內容將會繼續更新 時間過得真快,《client-go實戰》系列已是兩年前的作品,近期工作中再次用到clie ...
  • 一、導語 幾天前Oracle剛剛發佈了Java21, 由於這是最新的LTS版本,引起了大家的關註。 我也第一時間在個人項目中進行了升級體驗。 一探究竟,和大家分享。 二、Java21更新內容介紹 官方release公告: https://jdk.java.net/21/release-notes 開 ...
  • 一、背景: 需要對當前公司所有的項目進行代碼行數的統計 二、 可實現方式 1.腳本:通過git腳本將所有的項目拉下來並然後通過進行代碼行數的統計 樣例: echo 創建項目對應的文件夾 mkdir 項目名稱echo 切到創建的文件夾中 cd 項目名稱echo 進行git初始化 git init ec ...
  • 配置文件中的敏感信息,如密碼,賬號這些都應該是秘文的,在程式獲取時,再將它們動態解密,這樣保證了配置信息的安全;在springboot中,有個resources\META-INF\spring.factories文件,他幫我們完成了自動裝配,開發過starter包的同學應該不會陌生,而在這個文件里, ...
  • 直方圖,又稱質量分佈圖,用於表示數據的分佈情況,是一種常見的統計圖表。 一般用橫軸表示數據區間,縱軸表示分佈情況,柱子越高,則落在該區間的數量越大。構建直方圖時,首先首先就是對數據劃分區間,通俗的說即是劃定有幾根柱子(比如,1980年~2020年的數據,每5年劃分一個區間的話,共8個區間)。接著,對 ...
  • 本節將向讀者介紹如何使用鍵盤滑鼠操控模擬技術,鍵盤滑鼠操控模擬技術是一種非常實用的技術,可以自動化執行一些重覆性的任務,提高工作效率,在Windows系統下,通過使用各種鍵盤滑鼠控制函數實現動態捕捉和模擬特定功能的操作。有時我們經常需要進行重覆性的滑鼠操作,例如繁瑣的點擊、拖拽。這些任務可能消耗大量... ...
  • 基於java應急救援物資管理系統設計與實現,可適用於java物資系統,java物資救援管理系統,springboot應急救援物資管理系統,java物資分配管理系統,javaWeb應急救援物資管理系統設計與實現,物資進銷存管理系統,物資入庫出庫管理系統,物資申領系統等等 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...