【问题标题】:socket io event fires multiple timessocket io 事件触发多次
【发布时间】:2019-09-20 16:53:32
【问题描述】:

我在这里搜索过类似的问题,但没有一个对我有用。

我知道有些人建议不要在另一个事件中使用套接字,但我不知道如何在有事件时触发套接字。

所以我在另一个事件中初始化了套接字,该事件每次发生时都会更新。但是套接字连接在每次新更新时都会重复以前的结果。

我尝试在 componentDidMount 生命周期中初始化套接字,但它根本不起作用。

class UploadComponent extends Component {
  constructor (props) {
    super(props);

    this.state = {
      endpoint: "http://localhost:3000",
    }

    this.uploadModal = this.uploadModal.bind(this);
  }

  uploadModal () {

     update.on('success', file => {
          let {endpoint} = this.state;
          let socket = socketIOClient(endpoint, {transports: ['websocket', 'polling', 'flashsocket']});

          socket.on('data', (mydata) => {
            console.log(mydata) // <-- This gets fired multiple times.
          })
      })

   }

// some more code //
}

我想在没有重复消息的情况下触发“更新”事件时触发套接字。

【问题讨论】:

    标签: javascript reactjs sockets websocket socket.io


    【解决方案1】:

    由于在 Angular 上使用 nodejs 多次发射套接字,所以我尝试通过 this.socket.removeListener( "Your On Event" ); 删除套接字侦听器,

    这帮助我解决了多个套接字调用的问题,试试吧,它可能会有所帮助!

    【讨论】:

      【解决方案2】:

      除非您可以保证success 只被调用一次,否则您需要在此函数之外初始化套接字连接/事件处理程序

      class UploadComponent extends Component {
        constructor (props) {
          super(props);
      
          const endpoint = "http://localhost:3000";
          this.state = { endpoint };
      
          this.uploadModal = this.uploadModal.bind(this);
          this.socket = socketIOClient(endpoint, {transports: ['websocket', 'polling', 'flashsocket']});
          this.socket.on('data', (mydata) => {
              console.log(mydata)
          })
        }
      
        uploadModal() {
          update.on('success', file => {
           // this.socket.emit perhaps?  
          })
        }
      }
      

      【讨论】:

      • 每当我上传文件时都会调用success。如果我一起上传5个文件,那么它将被调用5次。我想每次文件上传成功时触发socket。
      • @TedKhi 当你说“触发套接字”时,你的意思是你想向服务器发送一个事件还是你想通过data事件从服务器接收一些东西?
      • 我想通过数据事件从服务器接收。因为只要文件到达那里,服务器就会发送数据。 updata.on('success') 事件确认客户端文件上传成功。
      • @TedKhi 在这种情况下,那么我的建议会起作用。在构造函数中设置一次套接字(或者甚至在外部并传入道具,只要有意义),您就不会创建多个事件。如果您可以依赖通过data 接收到的数据,则不需要成功事件。
      • 你知道为什么服务器端的 io.on('connection', ...) 在发送数据之前要等待组件重新挂载吗?
      【解决方案3】:

      正如 James 所建议的,我已将套接字逻辑放入构造函数中。但它只是在我的组件重新安装后才被解雇。

      查看我的 nodejs 服务器代码后,我尝试替换

      // some code //
      io.on('connection', (client) => {
        client.emit('data', { 
                    image: true, 
                    buffer: imageBuffer.toString('base64'),
                    fileName: meta.name
        })
      })
      

      有了这个

      
      // some code //
      io.emit('data', { 
         image: true, 
         buffer: imageBuffer.toString('base64'),
         fileName: meta.name
      })
      

      它有效!

      我还必须在 componentWillUnmount 中关闭套接字以避免多个重复数据。

      【讨论】: