時間長了就不發(fā)數據給用戶端了 刷新瀏覽器也不會返回 是被阻塞了嗎?
請問下大家這一塊需要怎么優(yōu)化或者設置
get_box_record() 貼下
順便 寫一個這個看看,是否因為 緩沖區(qū)滿 不再發(fā)送數據,或者客戶端已斷開
public function onBufferFull(TcpConnection $connection)
{
echo "bufferFull and do not send again\n";
};
$worker->onBufferFull = function(TcpConnection $connection)
{
echo "bufferFull and do not send again\n";
};
還有個問題,get_box_record的定時器沒有關閉的邏輯,隨著get_box_record請求增多,定時器也會增加,久而久之可能會有成千萬的定時器,這樣感覺會有內存泄漏,而且這上萬定時器一起請求數據庫數據庫估計會掛。不用的定時器應該及時關閉才對
每次鏈接都創(chuàng)建一個定時器,而且從來不銷毀,最后結果只能是內存溢出.如果說里面涉及到連接數據庫,那直接可能耗死數據庫了.
看你代碼也沒有說需要傳遞什么參數,那說白了就是一個群發(fā)功能,啟動的時候創(chuàng)建一個定時器群發(fā)就是了
<?php
namespace app\index\controller;
use app\common\model\box\Box;
use app\common\model\box\BoxRecord;
use app\common\model\ornaments\Ornaments;
use app\common\model\system\Site;
use app\common\model\user\User;
use think\worker\Server;
use Workerman\Lib\Timer;
define('HEARTBEAT_TIME', 55);
class Worker extends Server{
protected $socket = "websocket://0.0.0.0:25648";
protected $processes = 1;
protected $cons = [];
/**
* 收到信息
* @param $connection
* @param $content
*/
public function onMessage($connection, $content){
$connection->maxSendBufferSize = 5 * 1024 * 1024;
if ($content == 'ping'){
$connection->lastMessageTime = time();
} else {
if(!isset($this->cons[$connection->id])){
$this->cons[$connection->id] = 1;
if (is_json($content)){
$data = json_decode($content, true);
if ($data){
$method = $data['method'];
switch ($method){
case 'get_box_record': //獲取開箱記錄
//首次執(zhí)行下記錄
$list = $this->get_box_record();
$connection->send(json_encode(['code' => 200, 'msg' => '獲取成功', 'method' => $method, 'list' => $list]));
$this->get_box_record_repeat($connection, $method);
break;
default:
$connection->send(json_encode(['code' => 400, 'msg' => '方法不存在']));
break;
}
} else {
$connection->send(json_encode(['code' => 401, 'msg' => '參數錯誤']));
}
} else {
$connection->send(json_encode(['code' => 402, 'msg' => '參數錯誤']));
}
}
}
}
/**
* 當連接建立時觸發(fā)的回調函數
* @param $connection
*/
public function onConnect($connection){
}
/**
* 當連接斷開時觸發(fā)的回調函數
* @param $connection
*/
public function onClose($connection){
unset($this->cons[$connection->id]);
}
/**
* 當客戶端的連接上發(fā)生錯誤時觸發(fā)
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg){
unset($this->cons[$connection->id]);
echo "error $code msg $msg";
}
/**
* 每個進程啟動
* @param $worker
*/
public function onWorkerStart($worker){
if ($worker->id === 0){
Timer::add(10, function() use ($worker){
$time_now = time();
foreach($worker->connections as $connection) {
// 有可能該connection還沒收到過消息,則lastMessageTime設置為當前時間
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通訊時間間隔大于心跳間隔,則認為客戶端已經下線,關閉連接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
$connection->close();
}
}
});
}
}
/**
* 發(fā)送內容
* @param $connection
* @param $data
*/
private function get_box_record_repeat($connection, $method){
Timer::add(5, function() use ($connection, $method){
// $list = $this->get_box_record();
$connection->send(json_encode(['code' => 200, 'msg' => '獲取成功', 'method' => $method, 'list' => []]));
$this->get_box_record_repeat($connection, $method);
}, [], false);
}
/**
* 獲取最近開箱記錄
*/
private function get_box_record(){
$box_record_model = new BoxRecord();
$user_model = new User();
$ornaments_model = new Ornaments();
$box_model = new Box();
$site_model = new Site();
$head = $site_model->getField(['ttid' => 1], 'head');
$list = $box_record_model->selListLimit(['type' => ['in', '1,4,5']], 20, 'ttid, uid, oid, bid, battle_id, type', 'time desc, ttid desc', function ($item) use ($user_model, $ornaments_model, $box_model, $head) {
$user = $user_model->getInfo(['ttid' => $item['uid']], 'name, portrait');
if (!stristr($user['portrait'], 'http')) $user['portrait'] = '/public/uploads/' . $user['portrait'];
$ornaments = $ornaments_model->getInfo(['ttid' => $item['oid']], 'name, img');
$box_name = '';
$bid = '';
switch ($item['type']){
case 1:
$bid = $item['bid'];
$box_name = $box_model->getField(['ttid' => $bid], 'name');
break;
case 4:
$bid = $item['bid'];
$box_name = $ornaments_model->getField(['ttid' => $bid], 'name');
break;
case 5:
$bid = $item['battle_id'];
break;
}
$new_item = [
'mark' => encrypt_key($item['ttid']),
'user' => $user,
'ornaments_name' => $ornaments['name'],
'ornaments_img' => $ornaments['img'],
'box_name' => $box_name,
'bid' => encrypt_key($bid),
'type' => $item['type'],
];
return $new_item;
});
return $list;
}
}
js端:
var ws, timeid;
function create(){
ws = new WebSocket("wss://{$Think.server.HTTP_HOST}/wss");
ws.onopen = function() {
ws.send(JSON.stringify({method:'get_box_record'}));
timeid = setInterval(function(){
ws.send("ping");
}, 10000);
};
ws.onmessage = function(e){
var data = JSON.parse(e.data);
var code = data.code;
var msg = data.msg;
var method = data.method;
var content = data.list;
if (code == 200){
eval(method)(content);
} else {
// alert(msg);
}
};
ws.onclose = function(){
clearInterval(timeid);
setTimeout(function(){
create();
}, 1000);
}
}
create();
在 onWorkerStart 加
Timer::add(5, function () use ($worker) {
$list = get_box_record();
foreach ($worker->connections as $connection) {
if (empty($connection->get_box_record)) {
continue;
}
$method = $connection->get_box_record;
$connection->send(json_encode(['code' => 200, 'msg' => '獲取成功', 'method' => $method, 'list' => $list]));
}
});
在 case 'get_box_record': //獲取開箱記錄 下面加
$connection->get_box_record = $method;
然后把你自己定時器去掉,
再把
if ($worker->id === 0){
}去掉.