Node.js 如何在快速路由中使用 socket.io

     2023-02-22     262

关键词:

【中文标题】Node.js 如何在快速路由中使用 socket.io【英文标题】:Node.js how to use socket.io in express route 【发布时间】:2019-10-17 16:43:27 【问题描述】:

在我的一个 node.js 脚本中,我尝试在快速路由中使用 socket.io。我发现了许多类似的问题,并尝试按照建议实施解决方案,但没有任何结果。可能是因为我对快递路线缺乏了解。我点击了以下链接,

How use socket.io in express routes with node.js

Use socket.io in expressjs routes instead of in main server.js file

这是我的 app.js

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);

const PORT = 3000;
server.listen(PORT);
console.log('Server is running');
var api = require('./routes/api');

//app.use('/api', api);
app.use('/api', (req, res) => 
res.sendFile(__dirname + '/api.html');
);

app.get('/', (req, res) => 
   res.send("this is home location");
);

./routes 文件夹中的路由文件 api.js

var express = require('express');
var router = express.Router();
var fs = require("fs");
var bodyParser = require('body-parser');

const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);

console.log("inside api route");

router.get('/', function(req, res, next) 
console.log("api route called");

const connections = [];
var jsonobj = [name:"john",score:345,name:"paul",score:678]

io.sockets.on('connection',(socket) => 
    connections.push(socket);
    console.log(' %s sockets is connected', connections.length); // this is not printing

    socket.on('disconnect', () => 
       connections.splice(connections.indexOf(socket), 1);
    );

    socket.emit('server message', jsonobj);

 ); 
    //res.send(jsonobj) 
);

module.exports = router;

Socket.emit 未在我在路由使用时呈现的 html 页面上显示数据。我的html代码是,

//api.html

<!DOCTYPE html>
<html lang="en">

<body>
   <div class="container">
      <h1 class="jumbotron">
         Node js Socket io with  socket route example
      </h1>
      <div class="results">results</div>      
   </div>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
   <script>
    jQuery(document).ready(function() 
       var socket = io.connect();
       var jsondata = "";

       socket.on('server message', function(data)
         console.log('got data from server',data)
         jsondata = JSON.stringify(data);
         //console.log('jsondata',jsondata)
         $('.results').html(jsondata);
       );
    );   
 </script>
</body>
</html>

请建议我应该在 html 页面中获取路由套接字数据的内容。 谢谢

【问题讨论】:

尝试拨打http://localhost:3000/api/api/ 感谢@Vikash。是的,它奏效了。但怎么会?以及如何使它适用于“localhost:3000/api”。请提出建议。 因为在 app.use 和 router.get 这两个地方你都给出了相同的路由字符串'/api' 嗨@Vikash Singh,这没有按预期工作。它没有在 html 页面上显示套接字数据。 【参考方案1】:

乍一看,您似乎将 URL 前缀删除了两次。一次在 app.js 中,再次在 api.js 中。

试试 localhost:port/api/api

如果是这种情况,请更改

router.get('/api', function(req, res, next)

router.get('/', function(req, res, next)

这将允许您点击 localhost:port/api 并访问您的端点。

【讨论】:

嗨@user3424216,我很遗憾地说,但它仍然无法正常工作。我通过解决方案得到的响应是因为 res.send(jsonobj),而不是套接字。我试图在 html 中获取套接字,但它没有显示。我使用了“app.use('/api', (req, res) => res.sendFile (__dirname + '/api.html'); ); 我也会相应地编辑问题。【参考方案2】:

好的,让我们试着理解为什么首先需要通过路由内部的套接字发送数据。 Websocket 用于异步发送数据,而无需客户端发出请求。如果客户端已经在发出 HTTP 请求,那么您可以在 HTTP 响应中发送数据。

现在已经说过了,显然有一些用例,您必须根据某些 OTHER 用户请求的操作将数据发送到某些 WebSocket 通道。如果是这种情况,有多种方法可以做到这一点。一种简洁的方法是使用事件驱动架构

尝试这样的事情...在下面找到我的 cmets -

const express = require('express');
const router = express.Router();
const fs = require("fs");
const bodyParser = require('body-parser');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);

// move the socket connection outside of the route controller
// you must register the event listeners before anything else
const connections = [];

io.sockets.on('connection', (socket) => 
    connections.push(socket);
    console.log(' %s sockets is connected', connections.length); // this is not printing

    socket.on('disconnect', () => 
        connections.splice(connections.indexOf(socket), 1);
    );
);


// Event emitter for sending and receving custom events
const EventEmitter = require('events').EventEmitter;
const myEmitter = new EventEmitter();

myEmitter.on('my-event', function (jsonobj) 
    // do something here like broadcasting data to everyone
    // or you can check the connection with some logic and 
    // only send to relevant user
    connections.forEach(function(socket) 
        socket.emit('server message', jsonobj);
    );
);

router.get('/some-route', function (req, res, next)   
    const jsonobj = [ name: "john", score: 345 ,  name: "paul", score: 678 ]

    // emit your custom event with custom data
    myEmitter.emit('my-event', jsonobj);

    // send the response to avoid connection timeout
    res.send(ok: true);
);

module.exports = router;

【讨论】:

【参考方案3】:

我自己才刚刚开始理解这一点,但我认为你所在的位置很接近。

在你的 app.js 中添加到文件末尾:

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);

const PORT = 3000;
server.listen(PORT);
console.log('Server is running');
var api = require('./routes/api');

//app.use('/api', api);
app.use('/api', (req, res) => 
res.sendFile(__dirname + '/api.html');
);

app.get('/', (req, res) => 
   res.send("this is home location");
);

app.set("socketio", io);    // <== this line

将“io”变量存储在“socketio”中。您可以在任何其他“.js”文件中获取它。

var express = require('express');
var router = express.Router();
var fs = require("fs");
var bodyParser = require('body-parser');

const app = express();
const server = require('http').createServer(app);
//const io = require('socket.io').listen(server); // <== change this
const io = app.get("socketio"); // <== to this

console.log("inside api route");

router.get('/', function(req, res, next) 
console.log("api route called");

const connections = [];
var jsonobj = [name:"john",score:345,name:"paul",score:678]

io.sockets.on('connection',(socket) => 
    connections.push(socket);
    console.log(' %s sockets is connected', connections.length); // this is not printing

    socket.on('disconnect', () => 
       connections.splice(connections.indexOf(socket), 1);
    );

    socket.emit('server message', jsonobj);

 ); 
    //res.send(jsonobj) 
);

module.exports = router;

您应该使用其他“.js”文件中所需的任何其他变量来执行此操作。

另请注意,在您的文件中,您正在重新设置变量。最好像我用“io”向你展示的那样做。我设置的其他文件中唯一的变量是“app”本身。

希望这会有所帮助...

【讨论】:

嗨@WLGfx。 app.set("socketio", io);这条线看起来很吸引人。我尝试了这个解决方案,但没有奏效。我注意到它没有进入路由器部分。 “调用的 api 路由”未在“localhost:3000/api”上进入控制台【参考方案4】:

您尝试在单个项目中从两个不同的位置创建和启动服务器,这很不方便。你只需要一些清理,仅此而已。

app.js

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);


// Listen to sockets here instead of listening in routes/api.js
const connections = [];
var jsonobj = [name:"john",score:345,name:"paul",score:678]

io.sockets.on('connection',(socket) => 
  connections.push(socket);
  console.log(' %s sockets is connected', connections.length); // this is not printing

  socket.on('disconnect', () => 
     connections.splice(connections.indexOf(socket), 1);
  );

  socket.emit('server message', jsonobj);

);

const PORT = 3000;
server.listen(PORT);
console.log('Server is running');
var api = require('./routes/api');

//app.use('/api', api);
app.use('/api', (req, res) => 
res.sendFile(__dirname + '/api.html');
);

app.get('/', (req, res) => 
   res.send("this is home location");
);

routes/api.js

var express = require('express');
var router = express.Router();
var fs = require("fs");
var bodyParser = require('body-parser');

// Comment these out
// const app = express();
// const server = require('http').createServer(app);
// const io = require('socket.io').listen(server);

console.log("inside api route");

router.get('/', function(req, res, next) 
console.log("api route called");

  // Comment these out

  // const connections = [];
  // var jsonobj = [name:"john",score:345,name:"paul",score:678]

  // io.sockets.on('connection',(socket) => 
  //     connections.push(socket);
  //     console.log(' %s sockets is connected', connections.length); // this is not printing

  //     socket.on('disconnect', () => 
  //        connections.splice(connections.indexOf(socket), 1);
  //     );

  //     socket.emit('server message', jsonobj);

  //  ); 
      //res.send(jsonobj) 
);

module.exports = router;

保留您的 api.html 原样。希望这会有所帮助。

【讨论】:

尝试发出时,带有 Node.js 的 Socket.io 在路由文件中返回未定义

】尝试发出时,带有Node.js的Socket.io在路由文件中返回未定义【英文标题】:Socket.iowithNode.jsreturnsundefinedinroutefilewhentryingtoemit【发布时间】:2022-01-0204:27:58【问题描述】:我尝试使用socket.io从路由文件中发出数据,但当我调用路... 查看详情

如何在 node.js 中以角度使用 socket.io?

】如何在node.js中以角度使用socket.io?【英文标题】:Howtousesocket.ioinangularwithnode.js?【发布时间】:2019-03-0502:44:39【问题描述】:客户端我使用Angular6,服务器端我使用node.js。在Angular6控制台中,它打印消息并socket.ioid(message:"He... 查看详情

在 node.js 中,如何使用 socket.io 和 express 设置 redis?具体使用 RedisStore()

】在node.js中,如何使用socket.io和express设置redis?具体使用RedisStore()【英文标题】:Innode.js,howdoIsetuprediswithsocket.ioandexpress?SpecificallyusingRedisStore()【发布时间】:2012-09-2703:23:03【问题描述】:第一个问题我试图弄清楚会话、商店、... 查看详情

node.js:如何在 forEach 循环中使用异步调用实现路由方法?

】node.js:如何在forEach循环中使用异步调用实现路由方法?【英文标题】:node.js:howtoimplementaroutingmethodwithanasynccallinsideaforEachloop?【发布时间】:2015-12-1123:41:29【问题描述】:我必须实现这样的逻辑:varexpress=require(\'express\'),request... 查看详情

如何在 node.js 中接收 socket.io 客户端事件?

】如何在node.js中接收socket.io客户端事件?【英文标题】:Howtoreceivethesocket.ioclientsideeventinnode.js?【发布时间】:2013-03-0615:47:58【问题描述】:在我的应用程序中,我使用带有node.js的socket.io。在主应用程序文件中接收客户端事件工... 查看详情

如何在 node.js 和 socket.io 应用程序中组织套接字处理

】如何在node.js和socket.io应用程序中组织套接字处理【英文标题】:howtoorganizesockethandlinginnode.jsandsocket.ioapp【发布时间】:2013-12-2607:07:46【问题描述】:对于我的RESTapi,我为每条路由创建了一个文件。app.get(\'/api/user\',routes.user.ind... 查看详情

Socket.io:如果在快速路由中使用,事件会触发两次

】Socket.io:如果在快速路由中使用,事件会触发两次【英文标题】:Socket.io:Eventsfiringtwiceifusedinsideanexpressroute【发布时间】:2020-04-0310:56:14【问题描述】:我正在使用socketio开发一个聊天应用程序。我遇到的问题是,如果我将io.on... 查看详情

如何使用 Node JS 服务器在 Socket.io 中进行一对一聊天?

】如何使用NodeJS服务器在Socket.io中进行一对一聊天?【英文标题】:HowtodoOneonOnechatinSocket.iousingNodeJSserver?【发布时间】:2017-11-0520:58:54【问题描述】:我正在开发一个聊天应用程序。我在聊天演示应用程序中使用this。但这不是... 查看详情

如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]

】如何使用Socket.io和Node.js开发大型聊天应用程序[关闭]【英文标题】:HowtodevelopalargechatapplicationwithSocket.ioandNode.js[closed]【发布时间】:2012-08-3008:21:44【问题描述】:在过去的几个月里,我一直在使用Socket.io,开发了一个相当复... 查看详情

在 node.js 中如何实现节点模块,在 socket.io 中函数实现和创建实例是如何相同的

】在node.js中如何实现节点模块,在socket.io中函数实现和创建实例是如何相同的【英文标题】:Hownode-modulesareimplementedinnode.js,howfunctionimplementionandcreatinginstancearesameinsocket.io【发布时间】:2020-07-2506:30:32【问题描述】:constio=require(\... 查看详情

如何在 node.js 域中添加全局发射器?

】如何在node.js域中添加全局发射器?【英文标题】:Howtoaddinnode.jsdomainglobalemitter?【发布时间】:2013-07-2523:17:57【问题描述】:在我的node.js应用程序中,我曾经按域处理错误。该应用的架构如下所示:控制器。快速路由调用控制... 查看详情

在 Node.js 中组织路由

...】:我开始研究Node.js。我也在使用快递。我有一个问题-如何组织Web应用程序路由?所有示例都只是将所有这些app.get/post/put()处理程序放在app.js中,它工作得很好。这很好,但如果我拥有的不仅仅是一个简单的硬件博客?有没有... 查看详情

在 node.js 中使用 socket.io 通过 webrtc 广播实时音频

】在node.js中使用socket.io通过webrtc广播实时音频【英文标题】:Broadcastingliveaudiothroughwebrtcusingsocket.ioinnode.js【发布时间】:2015-08-1119:02:59【问题描述】:我正在尝试使用webrtc通过getUserMedia()获取音频并使用socket.io将其发送到服务器... 查看详情

vue.js如何使用socket.io?

参考技术A在很多需求业务中,都需要浏览器和服务器实时通信来实现功能,比如:扫码登录(扫码后,手机确认登录,PC网页完成登录并跳转)、订单语言提醒等,这些都是建立在两端实时通信的基础上的。对前端而言,来实现浏... 查看详情

如何在 node.js 中同时使用多个代理(代理)

】如何在node.js中同时使用多个代理(代理)【英文标题】:Howtousemultipleproxies(agents)atthesametimeinnode.js【发布时间】:2020-11-2213:26:12【问题描述】:我正在使用一个HTTP请求库,它可以使用http.Agent实例来通过特定代理路由您的请求... 查看详情

使用 socket.io 在 Node.js 中使用 MySql 数据库进行 HTML5 页面日志记录

】使用socket.io在Node.js中使用MySql数据库进行HTML5页面日志记录【英文标题】:HTML5pageloggingwithMySqldatabaseinNode.jswithsocket.io【发布时间】:2012-06-0419:50:51【问题描述】:我尝试使用HTML5+MySQL+Node.js+socket.io登录数据库,但失败了。请帮... 查看详情

Node.js + Socket.io 在套接字中存储数据

...【发布时间】:2013-08-2101:50:45【问题描述】:我目前正在使用node.js和socket.io模块构建一个应用程序。当用户连接时,我将针对用户的套接字存储特定于用户的数据。例如io.sockets.on(\'connection\',function(socket)socket. 查看详情

在 PHP 中使用 Node.js、Socket.io、Redis 的私人聊天消息

】在PHP中使用Node.js、Socket.io、Redis的私人聊天消息【英文标题】:PrivateChatMessagingusingNode.js,Socket.io,RedisinPHP【发布时间】:2016-09-1120:47:27【问题描述】:我正在为我的php应用程序中的实时私人消息传递系统工作。我的代码适用于... 查看详情