Socket.io事件发出多次

时间:2019-06-17 04:35:25

标签: node.js reactjs socket.io

我正在创建一个带有实时通知的聊天应用程序,该通知被发送,但是当它们仅应发送一次时,它们会随机发送。我在前端使用react和在后端使用node.js。

这是我的套接字事件:

socket.on('sendNotification', function(recipientId, notification) {
        console.log('send notification is firing');
      //find the room where the title is the recipient
      Room.findOne({'title':  recipientId}, function(err, room){
        if(err) throw err;
        console.log('this is the notification room found', room.id);
        socket.broadcast.to(room.id).emit('addNotification', notification);
      });
       socket.join(theRoom.id);
    });

// // //这应该在客户端上

   socket.on('joinYourNotificationRoom', function(userId){
    Room.findOne({'title' :userId}, function(err, room){
        if(err) throw 'thisd is the error to join your notifiaction room' + err;
        if(room){
          console.log('about to join a your notification room ');
        socket.join(room.id);
      }else{
        Room.create({
          title: userId
        }, function(err, newRoom, socket){
         socket.join(newRoom.id);
         console.log('new notifaction room created');
       });
     };
   });
});

在前端发送消息后,我在这里发送通知:

console.log('these are the users in the application', this.state.users);
let theUsers = [].concat.apply([], this.state.users);
console.log('theUsers', theUsers);

for(let user of theUsers){
  console.log('this is one of the users', user);
  if(user._id !== this.props.auth.user.id){
    let notification = {};
    let notificationText = user.name + " sent a message in room " + this.props.currentRoom.title;
    notification.recipient = user._id;
    notification.text = notificationText;
    console.log('join notification about to be submitted', user._id);
    this.state.socket.emit('sendNotification', user._id, notification);
  }
}

这是前端的通知室:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import io from 'socket.io-client';
import {notificationToServer, getNotifications} from 
 '../../actions';
import NotificationContainer from './NotificationContainer';
import axios from 'axios';

const socketURL="http://localhost:3000";
class Notifications extends Component {
  constructor(props){
    super(props);
    this.state = {
      notifications:[],
      socket:null
    }
    this.initSocket();
  }

  initSocket = () =>{
    const { user } = this.props.auth;
    const socket = io('http://127.0.0.1:5002', {
    transports: ['websocket'], jsonp: false });
    socket.connect();
    socket.on('connect', ()=>{
      this.setState({socket: socket});
      this.state.socket.emit('joinYourNotificationRoom', user.id);
      this.state.socket.on('addNotification', (notification)=>{
        this.props.notificationToServer(notification, ()=> {
          console.log('callback fired');
          //clear notifications
          this.props.getNotifications(user.id);
        });
      });
    })
  }

  componentWillMount(){
    const { user } = this.props.auth;
    this.props.getNotifications(user.id);
  }


  render() {
    console.log('these are the notifications', this.props.notification);
    let notifications = this.props.notifications.map((notification)=>
      <NotificationContainer notification={notification} />

    );
    return (
      <div className="App">
        <h6>Notifications</h6>
        {notifications}
      </div>
    );
  }
}

const mapStateToProps = state => {
  return{
    auth:state.auth,
    notifications: state.notifications.notifications
  };
};


export default connect(mapStateToProps,

{getNotifications,notificationToServer})(通知);

1 个答案:

答案 0 :(得分:0)

这应该是由于与服务器建立了多个连接并多次订阅了同一事件。在您的情况下,initSocket方法可以多次调用。在console.log方法内尝试initSocket,并确保只调用一次,因为可以创建多个Notification组件。

如果是这样,请将套接字连接逻辑移动到单独的文件(ES6模块)中,并通过该文件进行通信。