send
說明:
mixed Connection::send(mixed $data [,$raw = false])
向客戶端發(fā)送數(shù)據(jù)
參數(shù)
$data
要發(fā)送的數(shù)據(jù),如果在初始化Worker類時指定了協(xié)議,則會自動調(diào)用協(xié)議的encode方法,完成協(xié)議打包工作后發(fā)送給客戶端
$raw
是否發(fā)送原始數(shù)據(jù),即不調(diào)用協(xié)議的encode方法,默認(rèn)是false,即自動調(diào)用協(xié)議的encode方法
返回值
true 表示數(shù)據(jù)已經(jīng)成功寫入到該連接的操作系統(tǒng)層的socket發(fā)送緩沖區(qū)
null 表示數(shù)據(jù)已經(jīng)寫入到該連接的應(yīng)用層發(fā)送緩沖區(qū),等待向系統(tǒng)層socket發(fā)送緩沖區(qū)寫入
false 表示發(fā)送失敗,失敗原因可能是客戶端連接已經(jīng)關(guān)閉,或者該連接的應(yīng)用層發(fā)送緩沖區(qū)已滿
注意
send返回true
,僅僅代表數(shù)據(jù)已經(jīng)成功寫入到該連接的操作系統(tǒng)socket發(fā)送緩沖區(qū),并不意味著數(shù)據(jù)已經(jīng)成功的發(fā)送給對端socket接收緩沖區(qū),更不意味著對端應(yīng)用程序已經(jīng)從本地socket接收緩沖區(qū)讀取了數(shù)據(jù)。不過即便如此,只要send不返回false并且網(wǎng)絡(luò)沒有斷開,而且客戶端接收正常,數(shù)據(jù)基本上可以看做100%能發(fā)到對方的。
由于socket發(fā)送緩沖區(qū)的數(shù)據(jù)是由操作系統(tǒng)異步發(fā)送給對端的,操作系統(tǒng)并沒有給應(yīng)用層提供相應(yīng)確認(rèn)機制,所以應(yīng)用層無法得知socket發(fā)送緩沖區(qū)的數(shù)據(jù)何時開始發(fā)送,應(yīng)用層更無法得知socket發(fā)送緩沖區(qū)的數(shù)據(jù)是否發(fā)送成功。基于以上原因workerman無法直接提消息確認(rèn)接口。
如果業(yè)務(wù)需要保證每個消息客戶端都收到,可以在業(yè)務(wù)上增加一種確認(rèn)機制。確認(rèn)機制可能根據(jù)業(yè)務(wù)不同而不同,即使同樣的業(yè)務(wù)確認(rèn)機制也可以有多種方法。
例如聊天系統(tǒng)可以用這樣的確認(rèn)機制。把每條消息都存入數(shù)據(jù)庫,每條消息都有一個是否已讀字段??蛻舳嗣渴盏揭粭l消息向服務(wù)端發(fā)送一個確認(rèn)包,服務(wù)端將對應(yīng)消息置為已讀。當(dāng)客戶端連接到服務(wù)端時(一般是用戶登錄或者斷線重連),查詢數(shù)據(jù)庫是否有未讀的消息,有的話發(fā)給客戶端,同樣客戶端收到消息后通知服務(wù)端已讀。這樣可以保證每個消息對方都能收到。當(dāng)然開發(fā)者也可以用自己的確認(rèn)邏輯。
范例
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8484');
$worker->onMessage = function(TcpConnection $connection, $data)
{
// 會自動調(diào)用\Workerman\Protocols\Websocket::encode打包成websocket協(xié)議數(shù)據(jù)后發(fā)送
$connection->send("hello\n");
};
// 運行worker
Worker::runAll();