【问题标题】:How to disconnect a client for being inactive in chat for a specific time (socket.io, javascript)如何断开客户端在特定时间内处于非活动状态(socket.io,javascript)
【发布时间】:2020-05-02 02:56:14
【问题描述】:

在这个聊天应用程序中,我希望服务器断开在 x(可配置)时间内处于非活动状态的客户端。

我认为默认值为 60 秒,我认为我应该使用页面超时,如您在我的服务器文件中看到的那样,但不确定如何使其工作。

我们的想法是设置一个计时器,让我们假设 2 分钟不活动,然后您会被踢出,然后在 name.js 文件的 feedbackBox 函数中出现一条消息。

我的代码如下:

server.js

const PORT = 3000;
const io = require('socket.io')(PORT, {
  pingTimeout: 60000
});
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

const users = {};

io.on('connection', socket => {
  socket.on('new-user', name => {
    if (Object.values(users).includes(name)) {
      socket.emit('name-taken', name);
    }
    if (!Object.values(users).includes(name)) {
      users[socket.id] = name;
      socket.emit('user-accepted');
      socket.broadcast.emit('user-connected', name);
    }
  });
  socket.on('send-chat-message', message => {
    socket.broadcast.emit('chat-message', {
      message: message,
      name: users[socket.id]
    });
  });
  socket.on('disconnect', reason => {
    socket.broadcast.emit('user-disconnected', users[socket.id]);
    delete users[socket.id];
  });
});

name.js

const container = document.querySelector('.container');
const nameContainer = document.createElement('section');
const title = document.createElement('h1');
const form = document.createElement('form');
const nameInput = document.createElement('input');
const submitName = document.createElement('button');

title.innerText = 'Enter Your Name';
submitName.innerText = 'Connect';

const getName = () => {
  form.addEventListener('submit', e => {
    e.preventDefault();
    const name = nameInput.value;
    socket.emit('new-user', name);
    nameInput.value = '';
    socket.off('name-taken');
    socket.on('name-taken', () => {
      feedbackBox('Nickname already taken');
    });
    socket.off('user-accepted');
    socket.on('user-accepted', () => {
      title.classList.add('hide');
      nameContainer.classList.add('hide');
      addMessageForm();
    });
  });
};

const appendForm = () => {
  nameInput.classList.add('name_input');
  form.appendChild(nameInput);
  submitName.classList.add('submit_name');
  form.appendChild(submitName);
  nameContainer.appendChild(form);
  nameContainer.classList.add('name_container');
  nameContainer.classList.remove('hide');
  title.classList.remove('hide');
  title.classList.add('name_title');
  container.appendChild(title);
  container.appendChild(nameContainer);
  getName();
};

聊天.js

//const socket = io('http://localhost:3000');

const showFeedback = document.createElement('section');
const messageContainer = document.createElement('section');
const messageForm = document.createElement('form');
const messageInput = document.createElement('input');
const submitMessage = document.createElement('button');
const disconnectButton = document.createElement('button');

submitMessage.innerText = 'Send';
disconnectButton.innerText = 'X';

messageContainer.classList.add('message-container');
messageForm.classList.add('send-container');
messageInput.classList.add('message-input');
submitMessage.classList.add('send-button');
disconnectButton.classList.add('disconnect-button');

const addMessageForm = () => {
  showFeedback.classList.add('hide');
  messageContainer.classList.remove('hide');
  messageForm.classList.remove('hide');
  disconnectButton.classList.remove('hide');
  messageForm.appendChild(messageInput);
  messageForm.appendChild(submitMessage);
  container.appendChild(disconnectButton);
  container.appendChild(messageContainer);
  container.appendChild(messageForm);
  appendMessage('You joined');
};
//const name = prompt('What is your name?');
//socket.emit('new-user', name);

socket.on('chat-message', data => {
  appendMessage(`${data.name}: ${data.message}`);
});

socket.on('user-connected', name => {
  appendMessage(`${name} connected`);
});

socket.on('user-disconnected', name => {
  appendMessage(`${name} left the chat`);
});

messageForm.addEventListener('submit', e => {
  e.preventDefault();
  const message = messageInput.value;
  appendMessage(`You: ${message}`);
  socket.emit('send-chat-message', message);
  messageInput.value = '';
});

function appendMessage(message) {
  const messageElement = document.createElement('section');
  messageElement.innerText = message;
  messageContainer.append(messageElement);
}

const feedbackBox = message => {
  showFeedback.innerText = message;
  showFeedback.classList.add('feedback-I-disconnect');
  showFeedback.classList.remove('hide');
  container.appendChild(showFeedback);
};

disconnectButton.addEventListener('click', event => {
  if (event.target.classList.contains('disconnect-button')) {
    socket.disconnect();
    messageContainer.classList.add('hide');
    messageForm.classList.add('hide');
    disconnectButton.classList.add('hide');
    appendForm();
    feedbackBox('You disconnected from the chat');
  }
});

【问题讨论】:

    标签: javascript express socket.io


    【解决方案1】:

    您可以在套接字上设置超时并在每次收到来自该客户端的消息时清除超时:

    socket.on("sent-chat-message", message => {
        clearTimeout(socket.inactivityTimeout);
    
        socket.inactivityTimeout = setTimeout(() => socket.disconnect(true), 1000 * 60);
    });
    

    我不确定连接是否会自动重新建立,在这种情况下,您也必须在客户端执行此操作。

    【讨论】:

    • 我这样做了,但是没有用:socket.on('send-chat-message', message => { clearTimeout(socket.inactivityTimeout); socket.inactivityTimeout = setTimeout(socket.断开连接,1000 * 10); socket.broadcast.emit('chat-message', { message: message, name: users[socket.id] });
    • 你有没有记住超时是在第一条消息之后设置的?
    • 如果你的意思是有明确的超时,然后是广播消息的代码,然后设置超时然后是但没有工作。也许我错过了中间的一些步骤?
    • 我查看了 Socket.IO Server API 文档并编辑了我的答案。
    • 我现在正在研究完全相同的事情。您的回答有效,感谢您的帮助!
    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多