[attach]1348[/attach]
問(wèn)題一、如上圖,本地服務(wù)器 B需要接收來(lái)自客戶端client? A的數(shù)據(jù),然后將數(shù)據(jù)處理以后再發(fā)送給云服務(wù)器 C,C端處理數(shù)據(jù)以后再將處理的數(shù)據(jù)發(fā)送給B,B通過(guò)可以再次處理,發(fā)送給一個(gè)或者多個(gè)A端,
這三點(diǎn)直接都是長(zhǎng)連接,請(qǐng)問(wèn)使用gateway可以做到么,如果可以做到需要怎么配置,C端使用gateway沒(méi)有問(wèn)題,就是B端的gateway應(yīng)該怎么使用,
問(wèn)題二、B端使用兩個(gè)服務(wù)器做分布式部署,請(qǐng)問(wèn)可以在兩個(gè)服務(wù)器中運(yùn)行register,gateWay以及businessWorker,當(dāng)一個(gè)服務(wù)器出現(xiàn)問(wèn)題的時(shí)候,另一個(gè)服務(wù)器可以立即頂上,請(qǐng)問(wèn)這種可是實(shí)施么,如果可以,怎么實(shí)施
謝謝大神
?
Gateway框架的Events.php為何不能如下使用:
/**
* 當(dāng)客戶端發(fā)來(lái)消息時(shí)觸發(fā)
* @param int $client_id 連接id
* @param mixed $message 具體消息
*/
public static function onMessage($client_id, $message)
{
$gate = new Gateway();
$con = new AsyncTcpConnection('tcp://192.168.1.107:8282');
echo json_encode($con);
$con -> onConnect = function ()use($con){
$con->send('this is from BBB \r\n');
};
$con->onMessage = function ($con,$msg)use($gate){
global $client_id;
_**$gate::sendToClient($client_id, "this is from CCC said $msg\r\n");**_ };
$con->connect();
}
在$con->onMessage方法中調(diào)用Gateway::sendToClient()方法沒(méi)有作用。請(qǐng)問(wèn)大神這樣使用有什么特殊的地方要規(guī)避的么?謝謝大神
你要自己打日志,看下運(yùn)行到哪里了,沒(méi)有現(xiàn)場(chǎng)環(huán)境很難定位哪里問(wèn)題的。
比如$con->onMessage可能根本就沒(méi)運(yùn)行,自然就發(fā)不出去。另外gateway不用初始化,看下手冊(cè)用法
?
$con->onMessage是運(yùn)行了的,我在這個(gè)方法中打印數(shù)據(jù)是打印出來(lái)了的,但是調(diào)用Gateway::sendToClient(),A客戶端沒(méi)有反應(yīng)
你這個(gè)client_id放到全局變量里了,這個(gè)變量有可能會(huì)被其它請(qǐng)求更改,所以達(dá)不到你要的效果。
public static function onMessage($client_id, $message)
{
$con = new AsyncTcpConnection('tcp://192.168.1.107:8282');
echo json_encode($con);
$con -> onConnect = function ($con){
$con->send('this is from BBB \r\n');
};
$con->onMessage = function ($con,$msg)use($client_id){
echo "send to $client_id\n";
var_export(Gateway::isOnline($client_id));
Gateway::sendToClient($client_id, "this is from CCC said $msg\r\n");
$con->close();
};
$con->connect();
}?
另外記得及時(shí)關(guān)閉連接(最好加個(gè)定時(shí)器關(guān)閉),否則觸發(fā)多少請(qǐng)求就建立多少個(gè)連接,當(dāng)超過(guò)服務(wù)器限制會(huì)導(dǎo)致服務(wù)異常。
Gateway::isOnline($client_id)能排查是不是客戶端連接斷開了,斷開了就肯定無(wú)法發(fā)到了。
另外也可以抓包看下服務(wù)端到底發(fā)過(guò)去沒(méi),有可能是客戶端bug導(dǎo)致以為沒(méi)有發(fā)出去
?
謝謝大神的指教,這個(gè)問(wèn)題解決了,原因可能是使用全局的時(shí)候,$client_id再下次觸發(fā)onMessage的時(shí)候?yàn)镹ULL了,解決方法就是在使用的時(shí)候不需要全局,寫這個(gè)方法的時(shí)候use($client_id)就沒(méi)問(wèn)題了,麻煩大神了。我把可以使用的代碼寫在最后面,以供其他人使用。
在打印Gateway類庫(kù)中發(fā)現(xiàn)$address的地址為0.0.0.0:,發(fā)送的數(shù)據(jù)$gateway_data中的connection_id會(huì)變成null,如下圖所示。
[attach]1360[/attach]
?
下面的代碼是B端的代碼,C端的代碼無(wú)需太大改變<?php
/**
/**
use \GatewayWorker\Lib\Gateway;
use \Workerman\Connection\AsyncTcpConnection;
/**
onConnect 和 onClose 如果不需要可以不用實(shí)現(xiàn)并刪除
*/
class Events
{
private static $con = null;
public static function getCon()
{
if(self::$con){
return self::$con;
}else{
return new AsyncTcpConnection('ws://192.168.1.107:8282');
}
}
/**
/**
}
/**
不對(duì),你這樣是$con是一個(gè)全局的類,但是每次有請(qǐng)求就重置了$con->onMessage邏輯里的$client_id,最終發(fā)送會(huì)發(fā)送給最后一個(gè),也達(dá)不到你要的效果。
保持長(zhǎng)連接后要每個(gè)消息都傳遞屬于哪個(gè)client_id的處理結(jié)果,否則會(huì)混亂
?
<?php
/**
/**
use \GatewayWorker\Lib\Gateway;
use \Workerman\Connection\AsyncTcpConnection;
/**
onConnect 和 onClose 如果不需要可以不用實(shí)現(xiàn)并刪除
*/
class Events
{
public static $con = null;
public static function getCon()
{
if(self::$con){
return self::$con;
}else{
$con = new AsyncTcpConnection('ws://192.168.1.107:8282');
// 這里要求8282端口必須回傳client_id,告訴Events這個(gè)是哪個(gè)client_id的結(jié)果
$con->onMessage = function ($con,$msg){
$data = json_decode($msg, true);
$client_id = $data;
Gateway::sendToClient($client_id, "this is from CCC said $msg\r\n");
};
// 連接關(guān)閉了要把Events::$con 置空,否則消息永遠(yuǎn)發(fā)不出去
$con->close = function($con){
Events::$con = null;
};
$con->connect();
}
}
/**
/**
@param mixed $message 具體消息
*/
public static function onMessage($client_id, $message)
{
$con = self::getCon();
$con->send(json_encode());
}
/**
我又增加一臺(tái)服務(wù)器當(dāng)作A客戶端,測(cè)試了以下,發(fā)現(xiàn)沒(méi)有出現(xiàn)您說(shuō)的這個(gè)問(wèn)題,兩個(gè)客戶端都可以正確的接收到各個(gè)不同的傳遞過(guò)來(lái)的數(shù)據(jù)。謝謝大神給了另一種思路。我換您這個(gè)思路試一下。