簡體   English   中英

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

[英]Node.js how to use socket.io in express route

在我的一個node.js腳本中,我試圖在快速路由中使用socket.io。 我發現了許多類似的問題,並嘗試按照建議實施解決方案,但沒有任何結果。 可能是因為我對快車路線缺乏了解。 我按照以下鏈接,

如何在帶有node.js的快速路由中使用socket.io

在expressjs路由中使用socket.io而不是在main server.js文件中

這是我的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頁面中獲取路由套接字數據。 謝謝

乍一看,看起來您正在兩次修改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並訪問您的端點。

好吧,讓我們試着理解為什么你需要首先通過路由中的套接字發送數據。 Websockets用於異步發送數據,而客戶端不必發出請求。 如果客戶端已經在發出HTTP請求,那么您只需在HTTP響應中發送數據即可。

現在已經說過,顯然有一些用例需要根據某些OTHER用戶請求的操作將數據發送到某個WebSocket頻道。 如果是這種情況,有多種方法可以做到這一點。 一種干凈的方法是使用事件驅動的架構

嘗試這樣的事情......在下面找到我的評論 -

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;

我自己剛開始明白這一點,但我認為你所處的地方很近。

在你的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”本身。

希望這可以幫助...

您嘗試在單個項目中的兩個不同位置創建和啟動服務器,這很不方便。 你需要一些清理,就是這樣。

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");
});

路線/ 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 希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM