【问题标题】:socket.io not sending events to others in roomsocket.io 没有向房间里的其他人发送事件
【发布时间】:2021-08-20 02:38:54
【问题描述】:

所以我试图弄清楚一个非常基本的 socket.io 应用程序发生了什么。我通过让 2 个不同的选项卡注册为不同的用户并尝试查看另一个选项卡是否获得事件来对此进行测试。前端都没有接收到其他事件,但服务器确实可以正确接收到事件。我的前端是 vue.js,我认为我的代理设置正确。我不确定为什么连接到同一个房间的房间 2 人不会根据文档收到事件。

编辑:如果我删除 roomId 的 .to,则消息将仅复制给发送消息的用户:/不确定这是否意味着什么。

Edit2:这与 rabbitmq 适配器无法用于中继消息有关。通过删除该中间件,一切正常。

Node.js 服务器

import http from 'http';
import express from 'express';
import { Server } from 'socket.io';
const adapter = require('socket.io-amqp');

const app = express();
const server = http.createServer(app);
const io = new Server(server,{
  path: '/socket'
});

io.adapter(adapter('amqp://localhost'));

app.get('/',(req,res) => {
    res.send('<h1>Hello World, Again</h1>')
});

io.on('connection',(socket) => {
  
  const query = socket.handshake.query;
  const userId = query['userId'] as string;
  const roomId = query['roomId'] as string;
  if(!userId || !roomId)
  { 
    console.log('failed to connect - userId or roomId is undefined');
    socket.disconnect(); 
    return;
  } 
  
  socket.join(roomId);
  console.log(`connection - user: ${userId}, room: ${roomId}`);

  socket.on('newValue',(e) => {
    socket.to(roomId).emit('newValue',{
      userId: userId,
      value: e.value
    });

    console.log(`roomId: ${roomId}, userId: ${userId}, value: ${e.value}`);
  });

  socket.on('disconnect',(reason)=> {
    socket.to(roomId).emit('userDisconnect',{
      userId: userId
    });

    console.log(`disconnect - user: ${userId}, room: ${roomId}`);
  });

  socket.to(roomId).emit('newUser',{
    userId
  });
});
 
const PORT = 3000;
server.listen(PORT,() => {
    console.log(`listening on http://localhost:${PORT}`);
});

管理套接字的Vue.js视图

<template>
  <div class="room">
    <div class="p-grid">
      <div class="p-col-12">
        <playing-card :value="selectedValue" class="center-card"/>
      </div>
    </div>
    <div class="p-grid">
      <div class="p-col-12">
        <value-selector @change="onValueChange"/>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import 'vue-router';
import { userStore } from '../store/index';
import { io, Socket } from 'socket.io-client';
import { Options, Vue } from 'vue-class-component';
import ValueSelector from '../components/ValueSelector.vue';
import PlayingCard from '../components/PlayingCard.vue';

@Options({ 
  components: { 
    PlayingCard, ValueSelector
  }
})
export default class Room extends Vue {
  
  selectedValue = -1;
  private socket!: Socket | null;

  private closeSocket(): void {
    if(this.socket)
    {
      this.socket.close();
      this.socket = null;
    }
  }

  private configureSocket(): void {
    if(!this.socket)
    {
      this.socket = io({
        path: '/socket',
        reconnection: true,
        reconnectionDelayMax: 10000,
        query: {
          roomId: this.$route.params.roomId as string,
          userId: userStore.getters.userId as string
        }
      });

      this.socket.on('newValue',(e)=>{
        console.log(e);
      });

      this.socket.onAny((eventName,e)=>{
        console.log(eventName);
        console.log(e);
      });
    }
  }

  mounted(): void {
    this.configureSocket();
  }

  onValueChange(values: any) {
    this.selectedValue = values.newVal;
    if(this.socket)
    {
      this.socket.emit('newValue', {
        value: this.selectedValue
      });
    }
  }

  unmounted(): void {
    this.closeSocket();
  }
}
</script>

<style lang="scss" scoped>
.center-card {
  margin: auto;
}
</style>

Vue.config.js

module.exports = {
    devServer: {
      proxy: {
        '/socket': {
          target: 'http://localhost:3000',
          changeOrigin: true,
          ws: true,
        }
      }
    }
  }

服务器日志

[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/index.ts`
listening on http://localhost:3000
connection - user: ls91m4il, room: 123, socketId: 86zN3g6maJu1z0OzAAAB
connection - user: pq68znqa, room: 123, socketId: xvKKzXhEbCrnz_l_AAAD
roomId: 123, userId: ls91m4il, socketId, 86zN3g6maJu1z0OzAAAB value: 5
roomId: 123, userId: pq68znqa, socketId, xvKKzXhEbCrnz_l_AAAD value: 13

对于 onAny 或 on 订阅的事件响应以及匹配的命名事件,不会触发前端日志。

【问题讨论】:

  • 如果您的问题不是接收消息,请摆脱与它无关的 vue 内容。放入一些日志并找出发生了什么和没有发生什么。查看网络选项卡以查看是否收到消息。
  • 我的意思是 vue.js 正在使用代理......我不知道它是否相关。代码中有很多日志。消息到达服务器,然后客户端没有从那里收到任何消息......感觉这个评论是在没有真正注意我说的话的情况下发表的......
  • 一篇文章越长,阅读和理解你的实际问题就越困难。在这种情况下,听起来您没有正确使用 socket.io api。在这种情况下,第一步是消除其他所有内容并专注于使其正常工作。然后你可以读入vue的东西。在此过程中,您可能会弄清楚您的实际问题是什么,并且能够提出“为什么我的代码不起作用?”之外的问题

标签: node.js vue.js socket.io


【解决方案1】:

首先,socket.to(roomId).emit(...) 将向 roomId 中的每个套接字发送消息,socket 代表的客户端除外。如果您想发送到roomId 中的所有套接字,您将使用io.to(roomId).emit(...)。我不清楚您是要发送到所有套接字还是发送到除发起者之外的所有套接字,所以我想确保您了解这方面的内容。

在调试和日志记录方面可以确保自己能够解决问题的事项:

  1. 确保两个客户端都连接到您的服务器并保持连接。在 connectdisconnect 事件上记录实际的 socket.id 将为您提供很好的了解。

  2. 确保两个客户端都请求相同的roomId。如果每个roomId 不同,那么roomId 中将只有一个套接字,而socket.to().emit() 将没有其他人可以发送到。

  3. 确保发送newValue 消息的客户端没有发布导致页面重新加载的表单,因此旧套接字被断开并创建新套接字。登录点 #1 应该确保您没有看到这种情况发生。我提到这个主要是因为这是一个常见的错误,尽管我没有看到足够多的实际 HTML 页面来知道这对你来说是否是个问题。

  4. 在您的服务器上记录每条传入消息。不仅记录消息,还记录它所来自的socket.id。这将允许您重建整个消息流。

没有所有这些数据,我们就无法查明问题所在。这种类型的问题需要收集数据,然后跟踪线索,直到您可以更准确地看到正在发生的事情和没有发生的事情。如果我不得不冒险猜测,我想知道您是否对 #1 或 #2 有疑问。

【讨论】:

  • 我正在记录除 socketId 之外的所有内容,我已经添加了它,但仍然看到相同的内容。没有重新连接,消息发出新值,没有一个客户端得到它。 socket.io 是否不适用于开发机器上的多个浏览器选项卡?
  • @ChaseRLewis - 如果您希望我们能够进一步帮助您,我们需要查看您说您添加的所有日志。请将代码(包括所有新的 console.log() 语句)添加到您的问题中,并添加您在控制台中获得的结果日志。 Socket.io 适用于多个浏览器选项卡。
  • @ChaseRLewis - 我没有看到任何客户端代码专门监听 newValue 消息,这是您的服务器在 socket.to().emit() 中发送的消息。这肯定会解释为什么你没有收到它。你是否依赖this.socket.onAny(...)
  • 我依赖Any,因为newValue 不起作用。我现在已将两者都添加到代码中,但都没有响应。我还添加了请求的服务器日志。不会触发任何前端日志。服务器端代码显示服务器上的 newValue 被触发。
  • @ChaseRLewis - 我不知道。当您在服务器上收到newValue 消息时,我会尝试将一些固定消息发送回客户端。例如,socket.emit('gotNewValue') 看看您的客户是否可以直接从您的服务器接收任何消息 - 甚至不涉及房间?在您的客户端中为 gotNewValue 消息注册一个特定的侦听器。您需要简化以找到可行的方法,然后在此基础上重新构建。我完全不熟悉您使用代理和自定义适配器所做的事情,所以也许这也会导致问题。
猜你喜欢
  • 2021-09-04
  • 1970-01-01
  • 2022-08-21
  • 2015-03-20
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
相关资源
最近更新 更多