国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

使用workerman-stomp組件對接阿里iot的AMQP,接收數(shù)據(jù)包后對包的處理問題

Sdioo

php 版本

截圖

框架和stomp組件版本

截圖

情況描述

對接IOT的amqp的時候,已經建立正常連接。如下:
截圖

問題: 在進行多次數(shù)據(jù)包的傳送后, 云平臺的數(shù)據(jù)包接收 出現(xiàn) 不完整的情況。導致出現(xiàn):unknown cmd MESSAGE報錯。
代碼位置stomp包下的Client類的onConnectionMessage 方法
截圖

進一步排查TcpConnection下第557行public function baseRead($socket, $check_eof = true)方法處理數(shù)據(jù)包可能有問題。
因為前幾次包的數(shù)據(jù)解析正常,后面就一直不對了。

截圖
截圖

1770 5 2
5個回答

Tinywan

嘗試升級一下 workerman/workerman 版本

  • Sdioo 2022-05-11

    原因已經找到了,我覺得需要提交pr了。

walkor 打賞

包的長度是在 vendor/workerman/stomp/src/Protocols/Stomp.php 里的input方法計算的,看下這里是不是有什么問題,返回的長度不一致。

  • Sdioo 2022-05-11

    老大, 我在TcpConnection類下baseRead方法下,if ($this->_currentPackageLength === 0) { break; } 方法體內部追加 $this->_recvBuffer = '';作用是修復因Remove the current package from the receive buffer后, 接收下次數(shù)據(jù)包的時候 ( $this->_recvBuffer .= $buffer;) 導致數(shù)據(jù)包長度不一致。

Sdioo

$this->_recvBuffer .= $buffer; 原因就是recvBuffer 會拼接每次的新數(shù)據(jù)包,而當$this->_currentPackageLength為0 的時候,沒有clean 這個 $this->_recvBuffe.
截圖

截圖

  • walkor 2022-05-11

    應該不是workerman的問題。$this->_currentPackageLength 為0,說明當前包的數(shù)據(jù)不夠,無法計算包長,繼續(xù)等待數(shù)據(jù)。數(shù)據(jù)不夠肯定不能將已經收到的數(shù)據(jù)清零的,那樣就丟包了。
    stomp包的長度是在 vendor/workerman/stomp/src/Protocols/Stomp.php 里的input方法計算的,如果你每個包的長度都一樣,但是$this->_currentPackageLength,應該在input方法里找原因

  • Sdioo 2022-05-11

    首先,包上這樣的`$buffer = 'MESSAGE
    qos:1
    destination:/a1pyomK5esO//user/update
    message-id:1524185981254223361
    topic:/a1pyomK5esO/
    /user/update
    subscription:client-1
    generateTime:1652229230594

    {"breathe":"0","heartbeat":"0","onbed":"0","fanshen":"0","pressure":"0","deviation":"193"}' . "\0" . '' . "\0" . ''; 從buffer中 get full package后,余下的buffer 不夠input方法計算,返回$this->_currentPackageLength為0, 如果不添加$this->_recvBuffer = '', 繼續(xù)等待數(shù)據(jù)。等來下一次新的數(shù)據(jù)包發(fā)來的時候,$this->_recvBuffer .= $buffer;會拼接上一次余下的buffer,導致包的數(shù)據(jù)就不對了。然后 input 方法計算后的的長度,給$one_request_buffer = \substr($this->_recvBuffer, 0, $this->_currentPackageLength);` 得到數(shù)據(jù)就是錯誤的。

  • walkor 2022-05-11

    為什么會余下buffer,因為上一次的input計算的包長不對

  • walkor 2022-05-11

    不知道末尾為什么有兩個空字符,"\0" . '' . "\0",可能是這個原因。

  • Sdioo 2022-05-11

    對的,我也很疑惑

  • Sdioo 2022-05-11

    老大 我建議將 input 下的 $end_pos = strpos($buffer, "\x00"); 換成 $end_pos = strripos($buffer, "\x00");

  • Sdioo 2022-05-11

    這樣就可以了。。

  • walkor 2022-05-11

    也不能這樣,萬一它連續(xù)發(fā)了2個包就出問題了。我把多余的空字符當心跳吧

  • walkor 2022-05-11

    composer require workerman/stomp ^1.0.6 更新試下

  • Sdioo 2022-05-11

    解決了,老大考慮的周全

liziyu

mark

  • 暫無評論
Sdioo

截圖

阿里云末尾是以2個空字符結尾的,而我們input里面用的strpos($buffer, "\x00")只判斷了第一個,所有建議使用strripos($buffer, "\x00") 定位最后一位空字符位置

年代過于久遠,無法發(fā)表回答
??