如何通知用户有人在同一个房间里写作?

Posted

技术标签:

【中文标题】如何通知用户有人在同一个房间里写作?【英文标题】:How to notify user that someone is writing in the same room? 【发布时间】:2020-01-16 03:17:54 【问题描述】:

我正试图通知用户有人在同一个房间里写作。当我发出有人写它时,它工作正常。当我试图只通知同一个房间的用户时,问题就开始了。什么都没发生。提前致谢。

我想知道我在加入/离开房间时是否犯了任何错误,但我认为这不是问题,因为我可以在这些房间中发送消息。

server

var express = require("express");
var socket = require("socket.io");

var app = express();
var PORT = 5000;
server = app.listen(PORT, function() 
  console.log(`server is running on port $PORT`);
);

var rooms = ["general", "room1", "room2"];
var usernames = ;

io = socket(server);

io.on("connection", socket => 
  console.log(`connected user with id: $socket.id`);

  socket.on("adduser", username => 
    console.log(username);
    socket.username = username;
    console.log(`socket username = $socket.username`);
    socket.room = "general";
    console.log(`socket room: $socket.room`);
    usernames[username] = username;
    socket.join("general");
    socket.emit("updatechat", "SERVER", "you have connected to general room.");
    socket.broadcast
      .to("general")
      .emit("updatechat", "SERVER", username + " has connected to this room.");
    socket.emit("updaterooms", rooms, "general");
  );

  socket.on("switchRoom", (previousRoom, newroom) => 
    socket.leave(previousRoom);
    socket.join(newroom);
    console.log(socket.rooms);
    socket.emit(
      "updatechat",
      "SERVER",
      socket.username + " has left this room."
    );
    socket.broadcast
      .to(newroom)
      .emit("updatechat", "SERVER", socket.username + " has joined this room.");
    socket.emit("updaterooms", rooms, newroom);
  );

  socket.on("disconnect", () => 
    console.log(`disonnected user with id: $socket.id`);
    delete usernames[socket.username];
    io.sockets.emit("updateusers", usernames);
    socket.broadcast.emit(
      "updatechat",
      "SERVER",
      socket.username + " has disconnected."
    );
    socket.leave(socket.room);
  );

  socket.on("typing", currentRoom => 
    socket.broadcast.to(currentRoom).emit("typing");
    console.log("pisze");
  );

  socket.on("nottyping", user => 
    socket.broadcast.emit("nottyping", user);
    console.log("nie pisze");
  );

  socket.on("SEND_MESSAGE", function(data) 
    io.emit("RECEIVE_MESSAGE", data);
  );
);

client side

import React from "react";
import socketIOClient from "socket.io-client";

const socket = socketIOClient("http://localhost:5000");

class MessageInput extends React.Component 
  state = ;

  componentDidMount = props => 
    socket.on("typing", () => 
      console.log(`received typing`);
      this.props.handleUpdateTyping(true);
    );

    socket.on("nottyping", () => 
      console.log(`received not typing`);
      this.props.handleUpdateNotTyping(false);
    );

    socket.on("RECEIVE_MESSAGE", username => 
      console.log(`received message`);
      console.log(username);
      this.props.handleUpdateAddMessage(username);
    );
  ;

  timeoutFunction = () => 
    console.log("in timeout");
    this.props.handleUpdateIsTyping(false);
    socket.emit("nottyping");
  ;

  onKeyDownNotEnter = () => 
    if (this.props.isTyping === false) 
      this.props.handleUpdateIsTyping(true);
      var timeout = setTimeout(this.timeoutFunction, 1200);
      console.log(timeout);
      this.props.handleUpdateTimeout(timeout);
     else 
      socket.emit("typing", this.props.currentRoom);
      console.log("timeout to clear", this.props.timeoutValue);
      clearTimeout(this.props.timeoutValue);
      this.props.handleUpdateTimeout(setTimeout(this.timeoutFunction, 1200));
    
  ;

  handleEnterSend = e => 
    if (e.key === "Enter") 
      this.sendMessage(e);
    
  ;

  sendMessage = e => 
    socket.on("updatechat", function(username, data) 
      // $('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
    );
    e.preventDefault();
    socket.emit(
      "SEND_MESSAGE",
      
        author: this.props.username,
        message: this.props.message,
        currentRoom: this.props.currentRoom
      ,
      this.state.currentRoom
    );
    this.props.clearMessage();
  ;

  render() 
    return (
      <input
        value=this.props.value
        type="text"
        placeholder="Type your message here"
        onChange=event => 
          console.log(event.target.value);
          this.props.handleUpdateInputChanges(event.target.value);
          this.onKeyDownNotEnter();
        
        onKeyUp=this.handleEnterSend
      />
    );
  

export default MessageInput;

我希望只有当有人在房间里写作时才应该通知用户。当我使用 socket.broadcast.emit("typing") 而不是 socket.broadcast.to(currentRoom).emit("typing") 时,一切正常,但正在向所有房间发出写入通知。

【问题讨论】:

【参考方案1】:

我通过将当前房间从服务器传递给套接字事件并在客户端与客户端房间进行比较时检查它来解决它。

server side

socket.on("typing", data => 
    socket.broadcast.emit("typing", data.currentRoom);

client side

socket.on("typing", serverRoom => 
      if (this.props.currentRoom === serverRoom) 
        this.props.handleUpdateTyping(true);
      
    );

【讨论】:

以上是关于如何通知用户有人在同一个房间里写作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IOS 的 XMPP 群聊中接收通知

在断开连接事件中获取客户端当前所在的房间列表

信令服务器房间设置

Apple Watch - 如何安排并发症更新以与推送通知同步?

如何使用nodejs socket.io向特定房间中的用户发送打字警报和消息

无线 P2P。通知所有可用的对等点某些事件