一個客戶端通過Socket tcp協(xié)議連接到workerman后,源源不斷的向服務器傳輸數(shù)據(jù),數(shù)據(jù)用#號標識該條數(shù)據(jù)開始,用-號分割數(shù)據(jù)項,用!號標識該條數(shù)據(jù)結束。沒有包邊界,因為數(shù)據(jù)較小,每次接受到很多條數(shù)據(jù),通過onMessage打印出來看,如下,怎么才能將每條數(shù)據(jù)的第三列取出來,并且不丟數(shù)據(jù)呢?
數(shù)據(jù)樣列:
#558-A365485-954569-854121!
#558-B785485-521459--!
#558-A856915-556214-854121!
#558-A320015-777510--!
#558-A032154-002541-854121!
#558-A666214-669555-854121!
#558-A985115-222010--!
#558-A344512-663254-854121!
………………
每次觸發(fā)onMessage的時候可以echo到接受的數(shù)據(jù)條數(shù)不一樣,但是格式都如上,怎樣可以高效的將每條數(shù)據(jù)第三項數(shù)字取出來,最好能存變量,廣播給用戶組。
// 遠程websocket服務器發(fā)來消息時
$ws_connection->onMessage = function($connection, $data){
//echo "recv: $data\n";
這里怎樣寫高效的處理代碼??
};
558前面都有#號,被問答轉義了,數(shù)據(jù)樣例如下
#558-A365485-954569-854121!
#558-B785485-521459--!
#558-A856915-556214-854121!
#558-A320015-777510--!
#558-A032154-002541-854121!
#558-A666214-669555-854121!
#558-A985115-222010--!
#558-A344512-663254-854121!
要寫一個通訊協(xié)議來分包,看下手冊通訊協(xié)議部分。分包可以保證每次onMesage的數(shù)據(jù)是完整的,并且不會因為粘包導致數(shù)據(jù)丟失。
http://doc3.workerman.net/protocols/how-protocols.html
好的,謝謝,原來要自定義協(xié)議粘包。
還有一個,workerman中可接收的緩沖大小是否由TcpConnection::$maxSendBufferSize決定,假設因為onMesage的回調(diào)函數(shù)不能及時處理接收的數(shù)據(jù)流,導致$maxSendBufferSize占滿,客戶端是否在$maxSendBufferSize騰空前不能傳輸數(shù)據(jù)流。
maxSendBufferSize 是發(fā)送緩沖區(qū)的大小,當服務端發(fā)送速度大于客戶端接收速度時,數(shù)據(jù)會擠壓在發(fā)送緩沖區(qū),如果發(fā)送緩沖區(qū)滿,則觸發(fā)onBufferFull事件回調(diào),在這個事件回調(diào)中做處理(例如停止向客戶端繼續(xù)發(fā)送數(shù)據(jù))。
如果onMesage不能及時處理數(shù)據(jù),數(shù)據(jù)會首先數(shù)據(jù)會積壓在客戶端socket發(fā)送緩沖區(qū)(操作系統(tǒng)提供,大小約幾十K)和workerman服務器的socket接受緩沖區(qū)(操作系統(tǒng)提供,大小約幾十K),如果客戶端socket發(fā)送緩沖區(qū)滿,則客戶端調(diào)用socket寫操作將阻塞(block模式)或者立刻返回失敗(非阻塞模式),當服務端onMessage處理完畢再次讀取本地socket接收緩沖區(qū)數(shù)據(jù)后,客戶端socket發(fā)送緩沖區(qū)的數(shù)據(jù)會繼續(xù)發(fā)送過來到服務端socket接收緩沖區(qū),然后依次循環(huán)。
所以當服務端onMessage不能及時處理數(shù)據(jù),不會導致maxSendBufferSize滿,但是可能會導致數(shù)據(jù)在客戶端和服務端的socket緩沖區(qū)積壓。