[英]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() { /* ... */ }
}
但这带来了其他问题:
为什么在没有订阅的情况下,服务器重启后套接字仍可以工作?
现在问题已经倒转了。 第一次可以正常运行,但是如果服务器重新启动,浏览器将重新连接,但不重新订阅。 浏览器重新连接后,是否可以自动重新订阅事件?
谢谢!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.