将 socket.io 添加到现有的 Express 项目(前面有 React)

Posted

技术标签:

【中文标题】将 socket.io 添加到现有的 Express 项目(前面有 React)【英文标题】:Adding socket.io to an existing Express project (with React on the front) 【发布时间】:2020-02-11 03:37:24 【问题描述】:

我有一个用 Express 编写的现有项目,我在其中创建了一个消息传递系统。一切都在使用 POST/GET 方法(发送和接收消息)。 我想让它们实时出现,所以我在客户端和服务器端都安装了socket.io。在我的server.js 中,我添加了以下几行:

const http = require("http");
const io = require("socket.io");
const server = http.createServer();
const socket = io.listen(server);

并将我的app.listen(...) 更改为server.listen(...)。 还添加了:

socket.on("connection", socket => 
    console.log("New client connected");
    socket.on('test', (test) => 
        console.log('test-test')
    );

    socket.emit('hello', hello:'hello!');

        socket.on("disconnect", () => console.log("Client disconnected"));
);

在前面我把这样的代码放在componentDidMount 方法中:

const socket = socketIOClient();
socket.emit('test', test:'test!')
socket.on('hello', () => 
    console.log('aaa')
)

现在我遇到了 2 个问题。虽然 console.log() 工作正常,但我在 React 应用程序上收到错误:

WebSocket connection to 'ws://localhost:3000/sockjs-node/039/lmrt05dl/websocket' failed: WebSocket is closed before the connection is established.

这正常吗?

另外,当我在server.js 文件中将app.listen(...) 更改为server.listen(...) 时,我的路由停止工作。所有的 POST 和 GET 方法都不起作用,因为服务器无休止地响应。是否可以仅在特定路由文件中的特定方法上使用 socket.io?

我以这种方式保留路由:app.use('/api/user', user); 其中 user 是路由器文件。

更新: 完整的 server.js 要求:

const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const bodyparser = require('body-parser');
const passport = require('passport');

const user = require('./routes/api/v1/User');
const company = require('./routes/api/v1/Company');

const http = require("http");
const io = require("socket.io");


const app = express();

dotenv.config();
app.use(passport.initialize());
require('./config/seed');

require('./config/passport')(passport);
const server = http.createServer();
const socket = io.listen(server);

【问题讨论】:

我无法找到 express() 抱歉,忘记粘贴了。更新了我的帖子。 【参考方案1】:

您没有正确初始化服务器。尝试进行以下更改

// const server = http.createServer();
const server = http.createServer(app);

并确保您收听 server 而不是 io

server.listen(PORT_GOES_HERE)

[更新] 工作示例:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(80);
// WARNING: app.listen(80) will NOT work here!

// DO STUFF WITH EXPRESS SERVER
app.get('/', function (req, res) 
  res.sendFile(__dirname + '/index.html');
);

io.on('connection', function (socket) 
  socket.emit('news',  hello: 'world' );
  socket.on('my other event', function (data) 
    console.log(data);
  );
);

更多详情请查看:https://socket.io/docs/

【讨论】:

谢谢!有效!也许您也知道我的问题第二部分的答案,如果我可以在特定路由内接收和发出 websocket?比如说,只在router.get('/message', passport.authenticate('jwt', session: false), (req, res) => );? 您正在寻找命名空间。在此处阅读文档socket.io/docs/rooms-and-namespaces 如果这对您不起作用或不是您所要求的,请随时提示 谢谢,但据我了解,我无法从路由函数内部发出 socket.io?我问是因为我想用 JWT 保护这种连接。 解决了我的问题,结合这个答案:***.com/questions/36788831/…

以上是关于将 socket.io 添加到现有的 Express 项目(前面有 React)的主要内容,如果未能解决你的问题,请参考以下文章

将 UIView 添加到现有的 UIViewController

将 CheckBox 列添加到现有的 TableView

如何将多维数组添加到现有的 Spark DataFrame

如何将 Mailchimp 添加到现有的注册框

将核心数据添加到现有的 iPhone 项目

如何将新行添加到现有的 QTablewidget