javascript - Socket io 为同一个客户端多次发射
问题描述
我正在开发一个聊天应用程序,前端使用 angular 5,后端使用 nodeJS,使用 mongoDB 存储数据。我集成了socket io来实时发出消息
以下是我用来开发应用程序的代码。现在,当用户在文本框中触发消息时,我仅将消息发送给接收消息的用户。例如,如果 user1 正在向 user2 发送消息,则只有 user2 获得套接字事件,而不是所有其他连接的用户。所以我找到了一种使用 socket.id 向特定用户发射的方法
我没有使用相同的路由来呈现所有用户,我对不同的用户使用不同的路由,比如“John”是登录用户,用户可以在 /message/ABC、/message/ 中与其他用户聊天XYZ 等。
客户端 :
聊天组件.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();
};
});
}
服务器端 :
服务器.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
在套接字事件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在控制台收到消息如下
现在我正在导航以与另一个用户聊天,并且我在 /chat/kk 路线上,其中 kk 是另一个连接的用户。
现在,如果 kk 向 po 发送消息,我会收到两次消息。正如您在下面看到的,我导航到 /chat/kk ,我收到了两次消息。同样,如果我导航到另一个用户,我会收到三次消息,依此类推。Socket io 根据用户连接到套接字的次数向用户发出消息。
我只想要聊天应用程序的正常工作流程,而不是多次发送用户连接到客户端的消息。有解决方法吗?我想当我收到响应或者我为同一个客户端连接多次时,我在客户端回调中犯了错误。有人可以帮帮我吗。
谢谢 !
解决方案
当您将其描述为全局变量时,socket.io 不正确
您错误的原因是代码
constructor() {
this.socket = io("http://localhost:3000/");
}
您在 receiveMessage 函数内部删除和定义。它必须正常工作。
推荐阅读
- php - php-fpm 不加载相同的扩展 php-cli 是
- node.js - 解析作为字符串传递的多个 json - Socket.io、NodeJS 和 ExpressJS
- regex - 如何有条件地删除字符并在两者之间保留文本?
- c# - SelectPDF.Document.Footer 始终为空?
- google-cloud-platform - Google Cloud Build API 是否支持 API 密钥身份验证?
- encryption - 无法使用ionic3应用程序中的crypto-js解密crypto-js中的加密值
- php - WooCommerce 管理订单中发送电子邮件的自定义操作按钮
- c - 中断组合键(例如 CTRL-C)如何以及何时转换为信号?
- swift - Swift 4 - 使用 evaluateJavaScript 为 webKit 设置值
- javascript - 回调函数的自定义参数取决于事件