想請教下@walkor大神和各位大大。
我這邊有個(gè)需求是這樣的:
我們需要向外部服務(wù)器下訂單。他們下單時(shí)間是固定的(晚上的11點(diǎn)到12點(diǎn))。并且只提供給我們一個(gè)連接。而且需要登錄并且維持長連接。否則這個(gè)時(shí)間點(diǎn)就非常難連上了。因?yàn)檎{(diào)他們接口的不止我們一家。他們應(yīng)該也有限制。
我們是白天統(tǒng)計(jì)從11點(diǎn)到12點(diǎn) 每秒需要下單的數(shù)據(jù)。然后放入REDIS。
我們的數(shù)據(jù)類似這樣:
2021-08-10 11:00:00 [ ['id'=>100,'num'=>3], ['id'=>101,'num'=>3]]
2021-08-10 11:00:01 [ ['id'=>200,'num'=>1]]
我現(xiàn)在的處理是 連接成功后登錄成功后 就獲取這些數(shù)據(jù)。比如現(xiàn)在是11:00:00。這個(gè)時(shí)候我會獲取[ ['id'=>100,'num'=>3], ['id'=>101,'num'=>3]]然后發(fā)給他們下單。他們給我返回后我再次獲取然后再次發(fā)送。那就有一個(gè)問題。第一他們返回很快 就等于返回的時(shí)候還是11:00:00。那么我會再發(fā)一次。這個(gè)沒關(guān)系。因?yàn)樗麄兪怯袔齑娴亩沂窃?1:00:00到11:00:01中間放出,但是具體時(shí)間不告知。也就是我們不一定能搶得到單。
現(xiàn)在的問題就出在 如果他們響應(yīng)慢了,比如幾秒后他才能響應(yīng)。那么這幾秒我們一直在等他的響應(yīng)。不會獲取訂單也不會發(fā)送,也就導(dǎo)致這幾秒的訂單是根本連下都沒下。下也沒用了 因?yàn)榭隙〒尣坏?。?dǎo)致的結(jié)果就是連發(fā)都沒發(fā)。所以等于這幾秒的訂單壓根不可能搶到
我試過解決這個(gè)問題就是不等他響應(yīng)繼續(xù)發(fā)。我感覺他們程序應(yīng)該是做過處理。就是比如我 請求1延時(shí)了,那么再發(fā)請求2 他依然不會給我返回直到緩沖區(qū)滿。
現(xiàn)在這個(gè)問題搞的我很頭疼,完全沒思路了。想問下有沒有什么好的建議或者解決方法。
我的代碼如下:
<?php
use \Workerman\Lib\Timer;
use \Workerman\Connection\AsyncTcpConnection;
class Order
{
private $wbser;
private $islogin=false;
private $sendtime=0;
private $redis;
public function __construct(){
$this->redis=libredis::instance();
}
//像外部服務(wù)器發(fā)送
private function _send($data){
$this->sendtime=time();
$data=is_array($data) ? json_encode($data) : $data;
$this->wbser->send($data);
}
//從外部服務(wù)器接收
private function _recv($data){
$data=json_decode($data);
if($data['action']=='login' && $data['code']==200){
$this->islogin=true;
$this->_getorder();
}elseif($data['action']=='order' && $data['code']==200){
//處理下單邏輯
$this->redis->set("order:set_{$data['time']}",$data['data']);
//下單完成 繼續(xù)獲取
$this->_getorder();
}
}
//獲取要下單的數(shù)據(jù)
private function _getorder(){
//按時(shí)間獲取要下單的數(shù)據(jù)
$time=date('Y-m-d H:i:s');
$data = $this->redis->get("order:get_{$time}");
//不管有沒有都給他發(fā)
$this->_send(['action'=>'order','order'=>$data,'time'=>$time]);
}
//開啟
public function serverOnStart()
{
$context_option = [
'ssl' => [
'local_cert' => SSL_CERT_PATH,
'passphrase' => '',
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
]
];
//連接外部服務(wù)器
$this->wbser = new AsyncTcpConnection(HOST,$context_option);
$this->wbser->onConnect = function($connect)
{
//連接上后登陸
$data=['action'=>'login','username'=>'xxx','password'=>'xxx'];
$this->_send($data);
$this->_hreatbeat();
};
$this->wbser->onMessage = function($connect, $data)
{
$this->_recv($data);
};
$this->wbser->onClose = function()
{
$this->islogin=false;
};
$this->wbser->connect();
}
private function _hreatbeat(){
Timer::add(60,function()
{
if($this->islogin==true){
$space=time()-$this->sendtime;
if($space>240){
//超過4分鐘發(fā)送心跳
$this->_send(['action'=>'hreatbeat']);
}
}
});
}
}