Socket io为同一个客户端多次发出

时间:2018-06-13 23:16:31

标签: javascript node.js socket.io angular5

我正在使用前端的角度5和后端的nodeJS以及用于存储数据的mongoDB的聊天应用程序。我集成了socket io来实时发送消息

以下是我用来开发应用程序的代码。现在,当用户在文本框中触发消息时,我只向发送消息的用户发送消息。例如,如果user1正在向user2发送消息,则只有user2获取套接字事件而不是所有其他连接的用户。所以我找到了一种使用socket.id

向特定用户发出的方法

我没有使用相同的路线来渲染所有用户,我使用不同的路由到不同的用户,说“John”是登录用户,用户可以在/ message / ABC中与其他用户聊天, / message / XYZ等。

客户端:

chat.component.ts

ngOnInit() {
    this.loggedInUser = this.authService.getLoggedInUser();

    this.route.params
      .subscribe(params => {
        this.username = params['username'];
        this.receiveMessage();
      });
  }

sendMessage(message) {
    const messageDetails = {
      fromUsername : this.loggedInUser.username,
      message      : (message).trim(),
      toUsername   : this.username
    };

    this.socketService
      .sendMessage(messageDetails);
  }

  receiveMessage() {
    this.socketService
      .receiveMessage()
      .subscribe(
        (message : Message) => {
          console.log(message);
      });
  }

socket.service.client.ts

import * as io from 'socket.io-client';


private BASE_URL = AppConstants.ApiEndPoint.socketUrl;
private socket;

constructor() {
  this.socket = io("http://localhost:3000/");
}


sendMessage(messageDetails) {
    this.socket.emit('addMessage', messageDetails);
  }

  receiveMessage() {
    return new Observable(observer => {
      this.socket.on('addMessageResponse', function (message) {
        observer.next(message);
      });
      return () => {
        this.socket.disconnect();
      };
    });
  }

服务器端:

server.js

我正在使用express作为中间件并将服务器实例传递到服务器端的套接字

const http       = require('http');
const app        = express();
const server = http.createServer(app);

require("./server/services/socket.service.server")(server);

server.listen(port);

Socket.service.server.js

在socket事件 addMessage 上,我将消息添加到我的数据库,然后从我的用户模型呈现toUser的socketId,因此仅向目标用户发送。

module.exports = function (server) {

  var socketIo     = require('socket.io');
  var userModel    = require("../models/user/user.model.server");
  var messageModel = require("../models/message/message.model.server");

  const io = socketIo(server);

  io.on('connection', function(socket) {

    socket.on('addMessage', function (messageDetails) {
      messageModel
        .createMessage(messageDetails)
        .then(function (message) {
          userModel
            .findUserByUsername(message.toUsername)
            .then(function (user) {
              var socketId = user.socketId;
              io.to(socketId).emit('addMessageResponse', message);
            });
        });
    })

  });
};

现在,消息将发送到特定用户的客户端。这工作正常,但我收到的消息是用户连接到客户端的次数。

例如,我使用 PO 登录我正在路线/ chat / ok,其中ok是连接用户,ok向po发送消息。 PO在控制台中接收消息,如下所示

screenshot 1

现在我正在导航与其他用户聊天,我正在路线/ chat / kk,其中kk是另一个连接用户。

现在,如果kk向po发送消息,我将收到该消息两次。如下所示,我导航到/ chat / kk,我收到了两次消息。同样,如果我导航到另一个用户,我会收到三次消息,依此类推。 Socket io向用户发出一条消息,告知用户连接到套接字的次数。

Screenshot 2

我只想要聊天应用程序的正常工作流程,并且不会在用户连接到客户端的情况下多次发出消息。有解决方法吗?当我收到响应或者我为同一个客户端多次连接时,我想我在客户端回调中犯了错误。有人可以帮帮我吗。

谢谢!

1 个答案:

答案 0 :(得分:2)

当您将其描述为全局变量时,它在socket.io上是不正确的
错误的原因是代码

constructor() {
  this.socket = io("http://localhost:3000/");
}

您删除并定义了receiveMessage函数的内部。它必须正常工作。