[attach]1348[/attach]
問題一、如上圖,本地服務(wù)器 B需要接收來自客戶端client? A的數(shù)據(jù),然后將數(shù)據(jù)處理以后再發(fā)送給云服務(wù)器 C,C端處理數(shù)據(jù)以后再將處理的數(shù)據(jù)發(fā)送給B,B通過可以再次處理,發(fā)送給一個或者多個A端,
這三點直接都是長連接,請問使用gateway可以做到么,如果可以做到需要怎么配置,C端使用gateway沒有問題,就是B端的gateway應(yīng)該怎么使用,
問題二、B端使用兩個服務(wù)器做分布式部署,請問可以在兩個服務(wù)器中運行register,gateWay以及businessWorker,當(dāng)一個服務(wù)器出現(xiàn)問題的時候,另一個服務(wù)器可以立即頂上,請問這種可是實施么,如果可以,怎么實施
謝謝大神
?
Gateway框架的Events.php為何不能如下使用:
/**
* 當(dāng)客戶端發(fā)來消息時觸發(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()方法沒有作用。請問大神這樣使用有什么特殊的地方要規(guī)避的么?謝謝大神
你這個client_id放到全局變量里了,這個變量有可能會被其它請求更改,所以達不到你要的效果。
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();
}?
另外記得及時關(guān)閉連接(最好加個定時器關(guān)閉),否則觸發(fā)多少請求就建立多少個連接,當(dāng)超過服務(wù)器限制會導(dǎo)致服務(wù)異常。
Gateway::isOnline($client_id)能排查是不是客戶端連接斷開了,斷開了就肯定無法發(fā)到了。
另外也可以抓包看下服務(wù)端到底發(fā)過去沒,有可能是客戶端bug導(dǎo)致以為沒有發(fā)出去
?
謝謝大神的指教,這個問題解決了,原因可能是使用全局的時候,$client_id再下次觸發(fā)onMessage的時候為NULL了,解決方法就是在使用的時候不需要全局,寫這個方法的時候use($client_id)就沒問題了,麻煩大神了。我把可以使用的代碼寫在最后面,以供其他人使用。
在打印Gateway類庫中發(fā)現(xiàn)$address的地址為0.0.0.0:,發(fā)送的數(shù)據(jù)$gateway_data中的connection_id會變成null,如下圖所示。
[attach]1360[/attach]
?
下面的代碼是B端的代碼,C端的代碼無需太大改變<?php
/**
/**
use \GatewayWorker\Lib\Gateway;
use \Workerman\Connection\AsyncTcpConnection;
/**
onConnect 和 onClose 如果不需要可以不用實現(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');
}
}
/**
/**
}
/**
不對,你這樣是$con是一個全局的類,但是每次有請求就重置了$con->onMessage邏輯里的$client_id,最終發(fā)送會發(fā)送給最后一個,也達不到你要的效果。
保持長連接后要每個消息都傳遞屬于哪個client_id的處理結(jié)果,否則會混亂
?
<?php
/**
/**
use \GatewayWorker\Lib\Gateway;
use \Workerman\Connection\AsyncTcpConnection;
/**
onConnect 和 onClose 如果不需要可以不用實現(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這個是哪個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 置空,否則消息永遠發(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());
}
/**
我又增加一臺服務(wù)器當(dāng)作A客戶端,測試了以下,發(fā)現(xiàn)沒有出現(xiàn)您說的這個問題,兩個客戶端都可以正確的接收到各個不同的傳遞過來的數(shù)據(jù)。謝謝大神給了另一種思路。我換您這個思路試一下。