這篇文章給大家分享的是有關(guān)swoole json不完整的解決方法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
成都網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、成都小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。核心團(tuán)隊均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗,服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:假山制作等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗,同時也獲得了客戶的一致贊揚!swoole json不完整怎么辦?
swoole客戶端與服務(wù)端收發(fā)數(shù)據(jù)完整性問題解決
一、下面這個實例,啟動swoole服務(wù)后,監(jiān)聽9501端口,接收從客戶端發(fā)來的數(shù)據(jù),原樣返回。
class Server { private $serv; public function __construct() { $this->serv = new swoole_server("127.0.0.1", 9501); $this->serv->set(array( 'worker_num' => 4, //一般設(shè)置為服務(wù)器CPU數(shù)的1-4倍 'daemonize' => 1, //以守護(hù)進(jìn)程執(zhí)行 'max_request' => 2000, 'dispatch_mode' => 2,//進(jìn)程數(shù)據(jù)包分配模式 1平均分配,2按FD取摸固定分配,3搶占式分配 'task_worker_num' => 8, //task進(jìn)程的數(shù)量 "task_ipc_mode " => 3 , //使用消息隊列通信,并設(shè)置為爭搶模式 "log_file" => "./log/taskqueueu.log" ,//日志 )); $this->serv->on('Receive', array($this,'onReceive'));//接收到數(shù)據(jù)時回調(diào)此函數(shù) $this->serv->start(); } public function onReceive(swoole_server $serv, $fd, $from_id, $data ) { $serv->send($fd, $data); usleep(500); //不加延時的話,經(jīng)常兩條數(shù)據(jù)被合并成一條返回了。 $serv->close($fd); } public function onClose(swoole_server $serv, $fd) { $serv->send($fd, 'CLOSED'); } }
直接new Server啟動服務(wù)端。
二、啟動swoole客戶端,向服務(wù)端發(fā)數(shù)據(jù),并接收返回。
$client = new swoole_client(SWOOLE_SOCK_TCP); if (!$client->connect('127.0.0.1', 9501, -1)) { exit("connect failed. Error: {$client->errCode}\n"); } $data=[ 'type'=>1, 'data'=>array( 'PlatformCode'=>'...........很長的數(shù)據(jù).', ) ]; $sender=$client->send(json_encode($data)."\r\n\r\n"); while($result = $client->recv()){ if($result=='CLOSED'){ echo "任務(wù)結(jié)束。byebye~\r\n"; break; }else{ echo $result; } } $client->close();
當(dāng)發(fā)送比較大的數(shù)據(jù)包時,會發(fā)現(xiàn)接收到的json包是不完整的,可以使用EOF協(xié)議處理的方式來解決,比如在服務(wù)端設(shè)置:
$serv->set( array('open_eof_split' => TRUE, 'package_eof' => "\r\n\r\n") );
這樣,'\r\n\r\n'就成為EOF協(xié)議結(jié)束符。
發(fā)送數(shù)據(jù)包時,在包結(jié)尾添加上'\r\n\r\n',接口數(shù)據(jù)時遇到這個字符就認(rèn)為數(shù)據(jù)接收完畢,如此就保證的數(shù)據(jù)的完整性。
注:數(shù)據(jù)包中不能出現(xiàn)'\r\n\r\n'字符,否則會出現(xiàn)分包錯誤。
Swoole的Server和異步Client都是在onReceive回調(diào)函數(shù)中處理數(shù)據(jù)包,當(dāng)設(shè)置了協(xié)議處理后,只有收到一個完整數(shù)據(jù)包時才會觸發(fā)onReceive事件。
另外一種方式,也可以預(yù)先設(shè)定好要發(fā)送的包的長度,如:
$server->set(array( 'open_length_check' => true, 'package_max_length' => 81920, 'package_length_type' => 'n', //see php pack() 'package_length_offset' => 0, 'package_body_offset' => 2, ));
可以固定包的長度來確保數(shù)據(jù)的完整性,官方注釋如下:
固定包頭的協(xié)議非常通用,在BAT的服務(wù)器程序中經(jīng)常能看到。這種協(xié)議的特點是一個數(shù)據(jù)包總是由包頭+包體2部分組成。包頭由一個字段指定了包體或整個包的長度,長度一般是使用2字節(jié)/4字節(jié)整數(shù)來表示。服務(wù)器收到包頭后,可以根據(jù)長度值來精確控制需要再接收多少數(shù)據(jù)就時完整的數(shù)據(jù)包。Swoole的配置可以很好的支持這種協(xié)議,可以靈活地設(shè)置4項參數(shù)應(yīng)對所有情況。
Swoole的Server和異步Client都是在onReceive回調(diào)函數(shù)中處理數(shù)據(jù)包,當(dāng)設(shè)置了協(xié)議處理后,只有收到一個完整數(shù)據(jù)包時才會觸發(fā)onReceive事件。同步客戶端在設(shè)置了協(xié)議處理后,調(diào)用 $client->recv() 不再需要傳入長度,recv函數(shù)在收到完整數(shù)據(jù)包或發(fā)生錯誤后返回。
感謝各位的閱讀!關(guān)于“swoole json不完整的解決方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!