这是我的代码:
客户端
var socket = io.connect('http://' + serverAddress ,{ reconnection: false, forceNew: true } );
socket.emit('monitorAddedNotify' , { video: sourceVideo , socketId: socket.id});
socket.on('disconnectThatSoc', function(){
socket.disconnect();
});
服务器端:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
socket.disconnect() 方法不起作用,为什么?
据我测试,它工作正常。 我们如何重现这个问题?
尝试按多次 F5 按钮进入页面并快速重新加载。
它对我也很好。
您使用哪种浏览器? 我正在使用最新的 Firefox,当我快速重新加载时,“用户已断开连接”不起作用:失望:
我也有问题。 在这些动作中,断开连接,但它来得比重新启动浏览器要晚得多。
浏览器:Chrome 55.0.2883.95(64 位)
socket.io:“^1.7.2”
嗨@ventaquil。 按住 F5 时断开连接事件没有触发,我遇到了同样的麻烦。 你克服了这个吗?
@giathinh910不是在给定延迟后触发的disconnect
事件(可能与pingTimeout
/ pingInterval
选项有关,在此处记录)?
@darrachequesne我的问题与上面描述的@ventaquil “尝试进入页面并通过多次按F5按钮快速重新加载”相同。 通常,当您刷新页面套接字连接时,会触发“断开”然后再次“连接”。 我依靠这两个事件来更新在线用户的数量。 但是,如果页面重新加载速度足够快,“断开连接”将不会触发,这会导致添加一些不存在的用户套接字 ID。 这些虚幻的人当然会在 pingTimeout 之后被移除。 目前我改变了保存socket id的方式,只显示在线用户,而不是socket的数量,问题可以解决。
我就是这样处理这个问题的。 我在客户端发出了一个发送者,它在服务器上调用心跳。
socket.on("heartbeat", function() {
// console.log('heartbeat called!');
hbeat[socket.id] = Date.now();
setTimeout(function() {
var now = Date.now();
if (now - hbeat[socket.id] > 5000) {
console.log('this socket id will be closed ' + socket.id);
if (addedUser) {
--onlineUsers;
removeFromLobby(socket.id);
try {
// this is the most important part
io.sockets.connected[socket.id].disconnect();
} catch (error) {
console.log(error)
}
}
}
now = null;
}, 6000);
});
我发现这个代码函数可以调用:
io.sockets.connected[socket.id].disconnect();
这仍然会发生。 它不必是 F5/刷新。 在某个阶段打开一个选项卡并很快将其关闭,导致不会触发断开连接。 很难重现,因为套接字非常快,尤其是在本地运行时。 我注意到在后台打开选项卡并打开其他选项卡有助于(本地)重现问题。 我认为这是一个应该解决的重要错误。
这里有同样的问题。 这是在我的游戏服务器上创建幽灵游戏
也许要手动断开客户端,您可以使用带有一些发射的功能。
我不知道这是否会有所帮助,但我想我得到了一些东西......也许......
客户:
function ManualSocketDisconnect() {
socket.emit("manual-disconnection", socket.id);
socket.close();
console.log("Socket Closed. ");
}
服务器:
io.on("connection", function(socket) {
console.log("User " + socket.id + " Connected. ");
socket.on("manual-disconnection", function(data) {
console.log("User Manually Disconnected. \n\tTheir ID: " + data);
});
});
对不起,但我可能在我的代码中留下了一些漏洞。 我不是专业人士。 🙁
我面临同样的问题!
我将在 ReactJS-ExpressJS 中给出示例。
这是将触发事件的情况,并封装在componentWillUnmount()
中。
我将比较两个事件,我将从componentWillUnmount()
触发
newMessage
:- 这会将消息广播到特定房间disconnect
:-(我希望它会工作,但它没有) 这个事件监听器有回调,它将断开连接。 我包含一个console.log()
只是为了确认回调是否命中。现在,我们开始:-
客户:-
这些事件正在被触发:-
componentDidMount() {
console.log(this.props)
chat.emit('authenticate', {
token: localStorage.getItem('auth'),
refreshToken: localStorage.getItem('refresh'),
projectId: this.props.projectId,
userId: this.props.userId,
});
chat.on('newMessage', (messageData) => {
console.log('------------newMessageReceived-------------');
this.props.messageReceived({ messages: this.props.messages, messageData }, () => {
console.log('callback');
this.setState({
messages: this.props.messages
})
})
console.log(messageData);
})
}
以下事件不会触发。
componentWillUnmount() {
chat.emit('disconnect','just disconnect);
}
将触发以下事件。(仅测试是否发出正常消息事件)
componentWillUnmount() {
chat.emit('newMEssage', {
messageHeader: {
sender: {
user: {
id: this.props.userId,
name: this.props.name
}
}
},
messageBody: 'hello',
});
}
没有运气
服务器:-
这是 expressJS 后端的代码
//下面的initializeChatSocket在app.js中被调用
function initializeChatSocket(server) {
projects.hasMany(projectTeam, { foreignKey: 'projectId' });
const io = socketIO(server);
const chat = io.of('/chat').on('connection', function (socket) {
console.log(
'----------------------------------------New Chat Connection Established-------------------------------------------------------------------------'
);
socket.auth = false;
socket.on('authenticate', function (data) {
console.log('\n\n\n\n', 'authenticate called', '\n\n\n\n', data, '\n\n\n');
try {
const dummyReq = {
headers: {
refreshtoken: data.refreshToken,
},
};
console.log('\n\n\n\n', 'before verify', '\n\n\n\n');
const userDetails = verifyJWTToken(dummyReq, data.token);
console.log('\n\n\n\n', 'after verify', '\n\n\n\n');
socket.userId = userDetails.userId;
socket.projectId = data.projectId;
projectTeam
.findAll({
where: {
[Op.and]: {
projectId: data.projectId,
userId: data.userId,
}
}
})
.then(projects => {
console.log('\n\n\n\n', JSON.stringify(projects), '\n\n\n\n');
if (projects.length === 1) {
socket.auth = true;
socket.join(socket.projectId);
console.log('User id:- ${userDetails.userId} linked to project id :- ${socket.projectId}');
} else {
console.log('User id:- ${userDetails.userId} not linked to project id :- ${socket.projectId}');
throw { message: 'User not linked to project' };
}
});
} catch (error) {
console.log(String(error));
socket.auth = false;
socket.disconnect(String(error));
}
});
socket.on('disconnectt', function() {
console.log('Client Disconnecting'); // This is not being fired :/
socket.removeAllListeners('newMessage');
socket.removeAllListeners('disconnect');
socket.removeAllListeners('authenticate');
socket.removeAllListeners('connection');
});
socket.on('newMessage', async function (messageData) {
console.log('-------------------------New Message----------------------', String(messageData));
//TODO Save Message in Database
try {
socket.broadcast.to(socket.projectId).emit('newMessage', messageData);
console.log('\n\n\n\n\n broadcast sent\n\n' + JSON.stringify(messageData) + '\n\n\n');
} catch (error) {
console.log('\n\n\n\n\n broadcast error\n\n\n\n\n');
console.log(String(error));
console.log(error);
//TODO Handle Message Sending Error
}
});
});
}
这是浏览器的任何问题还是我需要从堆栈溢出社区询问的其他问题?
@manjotsk我不确定您现在是否已修复它,但是在您的服务器端代码上,您正在侦听disconnectt
(注意双t
)但您的前端正在发射disconnect
。 此外,您可能不想发出disconnect
因为该事件应该在客户端断开连接时从客户端发送到服务器。
我的代码依赖于发出断开连接事件的套接字来防止重复的 ips——重新加载我的应用程序的用户很快就会被阻止,因为断开连接甚至永远不会触发!
@manjotsk我不确定您现在是否已修复它,但是在您的服务器端代码上,您正在侦听
disconnectt
(注意双t
)但您的前端正在发射disconnect
。 此外,您可能不想发出disconnect
因为该事件应该在客户端断开连接时从客户端发送到服务器。
disconnectt
是我使用的冒名顶替者别名! 谢谢你指出。 我会在两边重新检查。 而且,显然,实施是错误的! 我看得更清楚了! 谢谢@nathanheffley 👍 :)
@manjotsk什么?
并且只使用 socket.once 而不是 socket.on
“客户级别。”
例子:
socket.on('连接')
采用
socket.once('连接'
.
我的也一样
socket.on("message") { (dataArray, socketAck) -> Void in
if let data = dataArray.first as? Data{
do{
let objc = try JSONDecoder.init().decode(GetChatConversation.self, from: data)
completionHandler(objc,nil)
}
catch let error{
return completionHandler(nil,error.localizedDescription)
}
}else{
completionHandler(nil,"Cannot cast Array of Any to Data")
}
}
如果有人知道告诉我,请不要返回回调
你傻吗? 您正在等待客户端上的发射,但服务器上没有发射。 他妈的离开这里
这是一些真正的负能量,Ehsan666x。
我就是这样处理这个问题的。 我在客户端发出了一个发送者,它在服务器上调用心跳。
hbeat[socket.id] = Date.now();
我想知道应该从客户端发送什么hbeat
值?
而不是socket.disconnect()
或socket.emit('disconnect')
socket.close();
,它应该在服务器端触发'disconnect'
事件。 它对我有用。
最有用的评论
你傻吗? 您正在等待客户端上的发射,但服务器上没有发射。 他妈的离开这里