GatewayWorker使用两个websocket连接session丢失

项目开了两个websocket地址用相同的注册地址
192.168.100.96:5858
192.168.100.201:5858
我在websocket的onConnect时候设置了认证定时器 (我用的是GlobalTimer)
// 连接到来后,定时10秒关闭这个链接,需要10秒内发认证并删除定时器阻止关闭连接的执行
$auth_timer_id = GlobalTimer::add(2, function () use ($client_id) {
//错误提示.
//发送离线提示
Send::sendToClientClose($client_id, 'server', 'Sign', 'auth', 400);
}, null, false);
$_SESSION['auth_timer_id'] = $auth_timer_id;
$_SESSION['client_id'] = $client_id;
在message里的接收第一条信息里会在成功后删除定时器,但是$_SESSION会有时候为空,而且只在多个websocket同时连接时会发生,单独一个不会发生(我是同时连接两个websocket,一直刷新页面就会出现这个问题)
因为业务逻辑以后还会更多个,甚至5-10个websocket服务器,求大佬求救啊!
已邀请:

walkor

赞同来自:

如果你的session是在onMessage里设置的,那很可能为空,因为会出现只发起连接但是还没来得及发送数据连接就断开的情况。也就是onMessage根本没触发的情况。
 
请自行记录下日志就排查,在设置SESSION的地方记录日志,包括client_id。获取的地方也记录client_id日志。
 

黑老怪

赞同来自:

连接触发
public static function onConnect($client_id)
{
try {
// 连接到来后,定时10秒关闭这个链接,需要10秒内发认证并删除定时器阻止关闭连接的执行
$auth_timer_id = GlobalTimer::add(2, function () use ($client_id) {
//错误提示.
//发送离线提示
Send::sendToClientClose($client_id, 'server', 'Sign', 'auth', 400);
}, null, false);
$_SESSION['auth_timer_id'] = $auth_timer_id;
$_SESSION['client_id'] = $client_id;
} catch (Throwable $e) {
//错误日志记录
Other::ErrorLog('Events', 'onConnect', $e);
//workerman记录错误
\GatewayWorker\Gateway::log($e);
}
}
连接后客户端发送第一条消息就会出现空,如果我在客户端连接后延迟100毫秒就不会出现,或者只使用一个websocket连接也不会出现
public static function onMessage($client_id, $message)
{
if ($_SESSION === null) {
$_SESSION['client_id'] = $client_id;
}
Route::index($client_id, $message);
}
环境:
两个websocket服务器
2个BusinessWorker进程 第一个为定时器第二个为业务逻辑
客户端为node.js 业务逻辑为
打开窗口会在nodejs后台生成ws连接
const express = require('express');
const router = express.Router();
const request = require('request');
const webSocket = require("ws");
/* GET home page. */
router.get('/', function (req, res, next) {
request({
url: "http://poker3.freepks.com/robotGameData",
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: {id: '100000035'}
}, function (error, response, body) {
res.end(JSON.stringify(body));
if (body.code === 200) {
webSocketF(body.address, 1)
}
});

});
function webSocketF(address, roomId) {
let ws = [];
let msgId = 1;
for (let a = 0; a < address.length; a++) {
const websocketUrl = "ws://" + address[a].url;
const token = address[a].token;
ws[a] = new webSocket(websocketUrl);
ws[a].on("open", function () {
// console.log(a);
ws[a].send('{"type":"client","class":"Sign","method":"in","site":"web","msgId":"1","data":{"token":"' + token + '"}}')
});
ws[a].on("error", function (err) {
console.log("error: ", err);
});
ws[a].on("close", function () {
console.log(a);
// console.log(ws[a].length);
});
ws[a].on("message", function (data) {
msgId++;
data = JSON.parse(data);
route(ws, data, msgId, roomId);
});
}
}
function route(ws, data, msgId, roomId) {
if (msgId === 2) {
console.log(ws.length);
//发送给游戏加入房间
for (let a = 0; a < ws.length; a++) {
ws[a].send('{"type":"client","class":"Room","method":"join","site":"hall","msgId":"2","data":{"roomId":' + roomId + '}}')
}
}
}
module.exports = router;
这是为了写游戏机器人 所以会模拟用户触发行为

walkor

赞同来自:

估计你的GatewayWorker版本低了,升级试下

要回复问题请先登录注册