web-dev-qa-db-ja.com

Node.js Express Routeでsocket.ioの使い方

私のnode.jsスクリプトのいずれかで、私はExpress Routeでsocket.ioを使用しようとしています。私は似たような質問を見つけ、提案されているようにソリューションを実装しようとしましたが、何も起こりませんでした。私の高速道路の理解の欠如によるものかもしれません。私は以下のリンクをフォローしました、

node.jsを使用してExpress Routesでsocket.ioを使用する方法

main server.jsファイルの代わりにexpressjs routesのsocket.ioを使用

これは私の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");
});
 _

Routeファイルapi.js in ./routesフォルダ

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ページでルートソケットデータを取得することになっていることをお勧めします。ありがとう

8
usersam

私はこれを私自身を理解し始めていますが、私はあなたがどこにいるのかは近いと思います。

あなたの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
 _

それは "Socketio"で "io"変数を格納します。あなたは他の ".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」であなたを示したのと同じことをするのが良いです。他のファイルの唯一の変数は「アプリ」自体です。

お役に立てれば...

0
WLGfx

OK、最初の場所のルート内のソケットを介してデータを送信する必要があるのか​​を理解しようとしましょう。 WebSocketは、クライアントが要求をする必要なしにデータを非同期的に送信するためのものです。クライアントがすでにHTTPリクエストを行っている場合は、HTTPレスポンスにデータを送信できます。

今、そこに言ったことは、他のユーザーの要求の行動に基づいて一部のWebSocketチャネルにデータを送信しなければならないことが明確にいくつかのユースケースです。そうであれば、これを行う方法は複数あります。 1つのきれいな方法は,イベント駆動型アーキテクチャを使用することです。

このようなものを試してみてください...下にインラインで私のコメントを見つける -

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;
 _
0
Sohail