繁体   English   中英

Socket.io仅适用于重新连接

[英]Socket.io only works on reconnect

我正在构建一个连接到Nodejs API的React应用程序,并且正在尝试实现Socket.io库。 我按照互联网上的一些教程进行操作,现在我的代码如下所示:

API:

import express from 'express';
import socketIo from 'socket.io';
import http from 'http';

const app = express();
const port = 3300;

const server = http.createServer(app);
const io = socketIo({ 
    serveClient: false,
    transports: [ 'websocket', 'polling' ],
    pingTimeout: 3000,
    pingInterval: 3000,
    allowUpgrades: false,
    upgrade: false,
    cookie: false
}).listen(server);

io.on('connection', function(socket){
    console.log("------------------------- CONNECTED!!!");
    app.get('/change_name', (req, res) => {
        console.log("Change Name");
        const { name } = req.query;
        res.sendStatus(200);

        console.log('Emitting Event');
        socket.emit('name', name);
    });
});

server.listen(port, err => err ? throw err : console.log("Server online. Listening to port " + port);

在我的React应用程序中:

import React from "react";
import openSocket from 'socket.io-client';

export default class Header extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      name: "Thiago"
    };

    console.log("Open Socket");
    const socket = openSocket('http://localhost:3300', {
      transports: [ 'websocket', 'polling' ],
    }); 
    console.log("Set event listener");
    socket.on('name', name => {
      console.log('receiving event')
      this.setState({ name });
    });
  }

  render() { /* ... */ }
}

现在,问题是,只有在Web应用程序重新连接到Websocket的情况下,我才能使这项工作正常进行。 为了显示:

运行我的应用程序和API后,我在浏览器中点击localhost:8888以访问该应用程序。 API已成功记录------ CONNECTED并且在浏览器的“网络”标签中看不到任何错误,因此我猜想连接工作正常。 但是,当我按下/change_name路由时,什么也没发生。 该API会同时记录“ Change Name和“ Emmitting Event ,但浏览器似乎从未接收到它(未记录receiving event )。

现在,如果我要去终端重新启动我的API(无需刷新浏览器),首先我在浏览器中收到一条错误消息,说我的ws连接丢失了。 API再次开始运行后,我会看到-------- CONNECTED日志,这意味着浏览器已成功重新连接到服务器,如果再次点击change_name ,现在一切正常! 如果刷新浏览器,一切停止都会再次起作用,并且我需要再次重新启动API。

我已经在本地和远程服务器(AWS)中对此进行了测试,其行为是相同的。 在第一个连接中没有任何反应,重启API后浏览器自动重新连接,一切正常。

有谁知道是什么原因导致这种现象? 也许我在配置中缺少什么?

谢谢!

正如Steve在评论中指出的那样, 教程说明了如何正确实现socket.io。

好像我缺少订阅部分。 当我添加它时,一切开始起作用。 现在的代码是这样的:

API:

import express from 'express';
import socketIo from 'socket.io';
import http from 'http';

const app = express();
const port = 3300;

const server = http.createServer(app);
const io = socketIo({ 
    serveClient: false,
    transports: [ 'websocket', 'polling' ],
    pingTimeout: 3000,
    pingInterval: 3000,
    allowUpgrades: false,
    upgrade: false,
    cookie: false
}).listen(server);

io.on('connection', function(socket){
    console.log("------------------------- CONNECTED!!!");
    socket.on('subscribeToName', () => { // <---- add this
        app.get('/change_name', (req, res) => {
            console.log("Change Name");
            const { name } = req.query;
            res.sendStatus(200);

            console.log('Emitting Event');
            socket.emit('name', name);
        }); 
    });
});

server.listen(port, err => err ? throw err : console.log("Server online. Listening to port " + port);

在我的React应用程序中:

import React from "react";
import openSocket from 'socket.io-client';

export default class Header extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      name: "Thiago"
    };

    console.log("Open Socket");
    const socket = openSocket('http://localhost:3300', {
      transports: [ 'websocket', 'polling' ],
    }); 
    console.log("Set event listener");
    socket.on('name', name => {
      console.log('receiving event')
      this.setState({ name });
    });
    console.log("Subscribe to Listener");
    socket.emit('subscribeToName'); // <---- add this
  }

  render() { /* ... */ }
}

但这带来了其他问题:

  1. 为什么在没有订阅的情况下,服务器重启后套接字仍可以工作?

  2. 现在问题已经倒转了。 第一次可以正常运行,但是如果服务器重新启动,浏览器将重新连接,但不重新订阅。 浏览器重新连接后,是否可以自动重新订阅事件?

谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM