aqui está meu código:
lado do cliente
var socket = io.connect('http://' + serverAddress ,{ reconnection: false, forceNew: true } );
socket.emit('monitorAddedNotify' , { video: sourceVideo , socketId: socket.id});
socket.on('disconnectThatSoc', function(){
socket.disconnect();
});
lado do servidor:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
o método socket.disconnect() não funciona por quê?
Pelo que testei, funciona bem. Como podemos reproduzir o problema?
Tente entrar na página e recarregue rapidamente pressionando várias vezes o botão F5.
Funciona bem para mim também.
Que navegador você usa? Estou usando o Firefox mais recente e quando recarrego rapidamente o bage "usuário desconectado" não funciona :disappointed:
Eu também tenho o problema. Nestas ações, desconexão, mas vem muito depois do navegador reiniciado.
Navegador: Chrome 55.0.2883.95 (64 bits)
socket.io: "^1.7.2"
Olá @ventaquil. Estou com o mesmo problema que o evento de desconexão não dispara ao segurar F5. Você superou isso?
@giathinh910 não é o evento disconnect
disparado após um determinado atraso (que pode estar relacionado às opções pingTimeout
/ pingInterval
, documentadas aqui )?
@darrachequesne Meu problema é o mesmo que @ventaquil descrito acima "Tente entrar na página e recarregue rapidamente pressionando várias vezes o botão F5". Normalmente, quando você atualiza uma conexão de soquete de página, dispara "desconectar" e "conectar" novamente. Conto com esses 2 eventos para atualizar os números de usuários online. No entanto, se a página recarregar rápido o suficiente, o "desconectar" não será acionado, o que fará com que algum id de soquete de usuário inexistente seja adicionado. Essas pessoas irreais serão removidas após o pingTimeout, é claro. Atualmente eu mudo a forma de salvar o socket id que mostrará apenas o usuário online, não o número do socket e o problema pode ser resolvido.
Eu lidei com este problema desta forma. Eu fiz um emissor de emissão no cliente que está chamando a pulsação no servidor.
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);
});
Eu encontrei esta função de código para chamar:
io.sockets.connected[socket.id].disconnect();
Isso ainda acontece. Não precisa ser F5/atualizar. Abrir uma aba e fechá-la rapidamente em um determinado estágio, faz com que a desconexão não seja acionada. É difícil de reproduzir porque os soquetes são muito rápidos, especialmente quando executados localmente. Percebi que abrir a aba em segundo plano e ter outras abas abertas ajudou a reproduzir o problema (localmente). Eu acho que este é um bug importante que deve ser corrigido.
Tenho o mesmo problema aqui. Isso está criando jogos fantasmas no meu servidor de jogos
Talvez para desconectar manualmente o cliente, você pode usar uma função com alguma emissão.
Não sei se isso vai ajudar, mas acho que consegui alguma coisa... Talvez...
Cliente :
function ManualSocketDisconnect() {
socket.emit("manual-disconnection", socket.id);
socket.close();
console.log("Socket Closed. ");
}
Servidor :
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);
});
});
Desculpe, mas provavelmente deixei alguns buracos no meu código. Não sou profissional. 🙁
Eu estou enfrentando o mesmo problema!
Estarei dando o exemplo em ReactJS-ExpressJS.
Aqui está a situação, que irá disparar o evento, e está encapsulada em componentWillUnmount()
.
Estarei comparando dois eventos, que dispararei de componentWillUnmount()
newMessage
:- isso transmitirá a mensagem para uma sala específicadisconnect
:-(Esperava que funcionasse, mas não funciona) Este ouvinte de evento tem um retorno de chamada que será desconectado. Eu contive um console.log()
apenas para confirmar se o retorno de chamada é atingido.Agora vamos lá:-
Cliente:-
Estes eventos estão sendo acionados:-
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);
})
}
O evento seguinte não dispara.
componentWillUnmount() {
chat.emit('disconnect','just disconnect);
}
O evento a seguir será acionado. (apenas testando se o evento de mensagem normal é emitido)
componentWillUnmount() {
chat.emit('newMEssage', {
messageHeader: {
sender: {
user: {
id: this.props.userId,
name: this.props.name
}
}
},
messageBody: 'hello',
});
}
Sem sorte
Servidor:-
Aqui está o código no backend expressJS
//A seguir initializeChatSocket é chamado em 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
}
});
});
}
Isso é algum problema com o navegador ou outra coisa que eu preciso perguntar da comunidade stack-overflow?
@manjotsk Não tenho certeza se você já o corrigiu, mas no código do lado do servidor você está ouvindo disconnectt
(observe o duplo t
), mas seu front-end está emitindo disconnect
. Além disso, você provavelmente não deseja emitir disconnect
, pois esse evento deve ser enviado de cliente para servidor quando o cliente se desconecta.
Eu tenho um código que depende do soquete emitindo o evento de desconexão para evitar ips duplicados - os usuários que recarregam meu aplicativo rapidamente são bloqueados porque a desconexão nunca é acionada!
@manjotsk Não tenho certeza se você já o corrigiu, mas no código do lado do servidor você está ouvindo
disconnectt
(observe o duplot
), mas seu front-end está emitindodisconnect
. Além disso, você provavelmente não deseja emitirdisconnect
, pois esse evento deve ser enviado de cliente para servidor quando o cliente se desconecta.
disconnectt
era um alias impostor que eu estava usando! Obrigado por apontar. Vou verificar novamente com isso em ambos os lados. E, obviamente, a implementação estava errada! Eu tenho uma visão mais clara! Obrigado @nathanheffley 👍 :)
@manjotsk O quê?
e use apenas socket.once em vez de socket.on
"nível do cliente".
exemplo:
socket.on('conectar')
usar
socket.once('conectar'
.
mesmo aqui meu
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")
}
}
não retorne o callback se alguém souber me diga
você é burro? você está esperando por uma emissão no cliente, mas nenhuma emissão no servidor. foda-se daqui
Isso é uma verdadeira energia negativa, Ehsan666x.
Eu lidei com este problema desta forma. Eu fiz um emissor de emissão no cliente que está chamando a pulsação no servidor.
hbeat[socket.id] = Date.now();
Gostaria de saber qual hbeat
deve ser enviado do lado do cliente?
Em vez de socket.disconnect()
ou socket.emit('disconnect')
tente socket.close();
no lado do cliente e isso deve acionar o evento 'disconnect'
no lado do servidor. Funcionou para mim.
Comentários muito úteis
você é burro? você está esperando por uma emissão no cliente, mas nenhuma emissão no servidor. foda-se daqui