向swoole隊列發送長文章像博客推送,發現文章總是被截斷有亂碼
懷疑包被分拆導致。
後查看swoole文檔,發現幀定界有幾種方式:
open_length_check
打開包長檢測特性。包長檢測提供了固定包頭+包體這種格式協議的解析。啓用後,可以保證Worker進程onReceive每次都會收到一個完整的數據包。
長度協議提供了3個選項來控制協議細節。
package_length_type
包頭中某個字段作爲包長度的值,底層支持了10種長度類型。請參考 package_length_type
package_body_offset
從第幾個字節開始計算長度,一般有2種情況:
length的值包含了整個包(包頭+包體),package_body_offset 爲0
包頭長度爲N字節,length的值不包含包頭,僅包含包體,package_body_offset設置爲N
package_length_offset
length長度值在包頭的第幾個字節。
也就是說,swoole支持自己自定義server和client之間的通信協議,可以約定報文頭和報文題的長度及偏移字段
例如,報文格式如下:
struct
{
uint32_t type;
uint32_t uid;
uint32_t length;
uint32_t serid;
char body[0];
}
以上通信協議的設計中,包頭長度爲4個整型,16字節,length長度值在第3個整型處。因此package_length_offset設置爲8,0-3字節爲type,4-7字節爲uid,8-11字節爲length,12-15字節爲serid。
swoole server的配置如下:
$server->set(array(
'open_length_check' => true,
'package_max_length' => 81920,
'package_length_type' => 'N',
'package_length_offset' => 8,
'package_body_offset' => 16,
));
在我們項目中,採用指定長度的方式
'open_length_check' => true, 'dispatch_mode' => 1, 'package_length_type' => 'N', 'package_length_offset' => 0, //第N個字節是包長度的值 'package_body_offset' => 4, //第幾個字節開始計算長度 'package_max_length' => 2000000, //協議最大長度