時(shí)間長(zhǎng)了就不發(fā)數(shù)據(jù)給用戶端了 刷新瀏覽器也不會(huì)返回 是被阻塞了嗎?
請(qǐng)問(wèn)下大家這一塊需要怎么優(yōu)化或者設(shè)置
get_box_record() 貼下
順便 寫(xiě)一個(gè)這個(gè)看看,是否因?yàn)?緩沖區(qū)滿 不再發(fā)送數(shù)據(jù),或者客戶端已斷開(kāi)
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";
};
還有個(gè)問(wèn)題,get_box_record的定時(shí)器沒(méi)有關(guān)閉的邏輯,隨著get_box_record請(qǐng)求增多,定時(shí)器也會(huì)增加,久而久之可能會(huì)有成千萬(wàn)的定時(shí)器,這樣感覺(jué)會(huì)有內(nèi)存泄漏,而且這上萬(wàn)定時(shí)器一起請(qǐng)求數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)估計(jì)會(huì)掛。不用的定時(shí)器應(yīng)該及時(shí)關(guān)閉才對(duì)
每次鏈接都創(chuàng)建一個(gè)定時(shí)器,而且從來(lái)不銷毀,最后結(jié)果只能是內(nèi)存溢出.如果說(shuō)里面涉及到連接數(shù)據(jù)庫(kù),那直接可能耗死數(shù)據(jù)庫(kù)了.
看你代碼也沒(méi)有說(shuō)需要傳遞什么參數(shù),那說(shuō)白了就是一個(gè)群發(fā)功能,啟動(dòng)的時(shí)候創(chuàng)建一個(gè)定時(shí)器群發(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': //獲取開(kāi)箱記錄
//首次執(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' => '參數(shù)錯(cuò)誤']));
}
} else {
$connection->send(json_encode(['code' => 402, 'msg' => '參數(shù)錯(cuò)誤']));
}
}
}
}
/**
* 當(dāng)連接建立時(shí)觸發(fā)的回調(diào)函數(shù)
* @param $connection
*/
public function onConnect($connection){
}
/**
* 當(dāng)連接斷開(kāi)時(shí)觸發(fā)的回調(diào)函數(shù)
* @param $connection
*/
public function onClose($connection){
unset($this->cons[$connection->id]);
}
/**
* 當(dāng)客戶端的連接上發(fā)生錯(cuò)誤時(shí)觸發(fā)
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg){
unset($this->cons[$connection->id]);
echo "error $code msg $msg";
}
/**
* 每個(gè)進(jìn)程啟動(dòng)
* @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還沒(méi)收到過(guò)消息,則lastMessageTime設(shè)置為當(dāng)前時(shí)間
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通訊時(shí)間間隔大于心跳間隔,則認(rèn)為客戶端已經(jīng)下線,關(guān)閉連接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
$connection->close();
}
}
});
}
}
/**
* 發(fā)送內(nèi)容
* @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);
}
/**
* 獲取最近開(kāi)箱記錄
*/
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': //獲取開(kāi)箱記錄 下面加
$connection->get_box_record = $method;
然后把你自己定時(shí)器去掉,
再把
if ($worker->id === 0){
}去掉.