use \GatewayWorker\Lib\Gateway;
use \Workerman\Connection\AsyncTcpConnection;
use \Workerman\Events\EventInterface;
use \Workerman\Worker;
use \Workerman\Autoloader;
use \Workerman\WebServer;
use \GatewayWorker\BusinessWorker;
use \Workerman\Lib\Timer;
use Lib\JsonFormat;
use Lib\JsonToSql;
include_once __DIR__.'/../'.'Include/function.php';
include_once __DIR__.'/../'.'Include/config.db.php';
require_once __DIR__.'/../../'.'vendor/workerman/mysql-master/src/Connection.php';
// bussinessWorker 進(jìn)程
$worker = new BusinessWorker();
// worker名稱
$worker->name = 'M-BtcTrade-COM';
// bussinessWorker進(jìn)程數(shù)量
$worker->count = 1;
// 服務(wù)注冊(cè)地址
$worker->registerAddress = '127.0.0.1:1238';
// 心跳間隔25秒
define('HEARTBEAT_TIME', 25);
$worker->onWorkerStart = function()
{
// 設(shè)置訪問(wèn)對(duì)方主機(jī)的本地ip及端口以及ssl證書
$context_option = array(
// ssl選項(xiàng),參考http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// 本地證書路徑。 必須是 PEM 格式,并且包含本地的證書及私鑰。
//'local_cert' => '/your/path/to/pemfile',
// local_cert 文件的密碼。
//'passphrase' => 'your_pem_passphrase',
// 是否允許自簽名證書。
'allow_self_signed' => true,
// 是否需要驗(yàn)證 SSL 證書。
'verify_peer' => false,
'verify_peer_name' => false
)
);
// 每1秒執(zhí)行一次
$time_interval = 1;
$connect_time = time();
// 給connection對(duì)象臨時(shí)添加一個(gè)timer_id屬性保存定時(shí)器id
Timer::add($time_interval, function()
{
$coin_list = array("btc","eth","ltc","doge","ybc");
//print_r($coin_list);
foreach ($coin_list as $key=>$val){
$con = new AsyncTcpConnection("ssl://api.btctrade.com:443", $context_option);
$con->cointype = $val;
$con->send("GET /api/trades?coin=".$val." HTTP/1.1\r\nHost: api.btctrade.com\r\n\r\n");
$con->onMessage = function($con, $data)
{
$data_arr = explode("\r\n\r\n", $data, 2);
$data_arr1 = explode("\r\n", $data_arr);
$json_data = "btctrade_trade_".$con->cointype."cny";
$json_data = json_decode($data_arr1,true);
//print_r($json_data);
//echo $con->uri."\n";
//輸出數(shù)據(jù)進(jìn)行處理
..................................................
................................................
};
$con->connect();
$con->onClose = function($con)
{
//echo "connection closed\n";
};
//print_r($val);
// 設(shè)置以ssl加密方式訪問(wèn),使之成為wss
}
});
};
// 如果不是在根目錄啟動(dòng),則運(yùn)行runAll方法
if(!defined('GLOBAL_START')) {
Worker::runAll();
}
以上代碼是每秒鐘循環(huán)中抓取一下5個(gè)URL返回的JSON數(shù)據(jù)
現(xiàn)在的問(wèn)題是在$con->onMessage還未完全處理完數(shù)據(jù)之前,$con 對(duì)象就被下次循環(huán)重建了,從而造成數(shù)據(jù)丟失,請(qǐng)問(wèn)如何修改代碼才能避免這個(gè)問(wèn)題的出現(xiàn)呢?
這是5個(gè)不同的鏈接,互相不影響,不會(huì)有覆蓋。
你的問(wèn)題應(yīng)該是tcp數(shù)據(jù)被分包了,數(shù)據(jù)沒(méi)接收完整,onMessage里的數(shù)據(jù)是服務(wù)器響應(yīng)的部分?jǐn)?shù)據(jù)。你要根據(jù)http協(xié)議規(guī)則,讀取http包頭中包的長(zhǎng)度,然后根據(jù)長(zhǎng)度緩沖每次onMessage里的數(shù)據(jù),把每次onMessage里的的data數(shù)據(jù)拼接成一個(gè)完整的http數(shù)據(jù)才行
通過(guò)測(cè)試,$con->onMessage中輸出的print_r($data),都是完整的json格式數(shù)據(jù),$data的輸出內(nèi)容在附件中。
除了分包問(wèn)題,還有沒(méi)有其他可能性造成這種情況的出現(xiàn)?
ssl協(xié)議的$con->onMessage確實(shí)存在分包問(wèn)題
請(qǐng)問(wèn)AsyncTcpConnection的wss協(xié)議是否也存在分包問(wèn)題呢?