Pertanyaan Memisahkan file server dan logika socket.io di node.js


Saya cukup baru untuk node.js dan saya telah menemukan cukup rumit memisahkan proyek menjadi beberapa file sebagai proyek tumbuh dalam ukuran. Saya memiliki satu file besar sebelumnya yang berfungsi sebagai file server dan server Socket.IO untuk game multipemain HTML5. Saya idealnya ingin memisahkan file server, socket.IO logic (membaca informasi dari jaringan dan menulisnya ke buffer dengan stempel waktu, kemudian memancarkannya ke semua pemain lain), dan logika permainan.

Menggunakan contoh pertama dari socket.io untuk menunjukkan masalah saya, biasanya ada dua file. app.js adalah server dan index.html dikirim ke klien.

app.js:

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(80);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

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

index.html:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>

Untuk memisahkan server file dan logika server game, saya akan memerlukan fungsi "pengendali" didefinisikan dalam satu file, saya akan membutuhkan fungsi anonim yang menggunakan callback untuk io.sockets.on () untuk berada di file lain, dan saya akan membutuhkan file ketiga untuk berhasil memasukkan kedua file ini. Untuk saat ini saya telah mencoba yang berikut:

start.js:

var fileserver = require('./fileserver.js').start()
  , gameserver = require('./gameserver.js').start(fileserver);

fileserver.js:

var app = require('http').createServer(handler),
    fs = require('fs');

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

module.exports = {
    start: function() {
        app.listen(80);
        return app;
    }
}

gameserver:

var io = require('socket.io');

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

module.exports = {

    start: function(fileserver) {       
        io.listen(fileserver).on('connection', handler);
    }

}

Ini sepertinya berfungsi (konten statis disajikan dengan benar dan konsol dengan jelas menunjukkan jabat tangan dengan Socket.IO ketika klien terhubung) meskipun tidak ada data yang pernah dikirim. Seolah-olah socket.emit () dan socket.on () tidak pernah benar-benar dipanggil. Saya bahkan memodifikasi handler () di gameserver.js menambahkan console.log('User connected'); Namun ini tidak pernah ditampilkan.

Bagaimana saya bisa memiliki Socket.IO dalam satu file, file server di yang lain, dan masih mengharapkan keduanya beroperasi dengan benar?


66
2018-03-14 20:37


asal


Jawaban:


Dalam socket.io 0.8, Anda harus melampirkan acara menggunakan io.sockets.on('...'), kecuali Anda menggunakan ruang nama, sepertinya Anda melewatkan sockets bagian:

io.listen(fileserver).sockets.on('connection', handler)

Mungkin lebih baik untuk menghindari chaining seperti itu (Anda mungkin ingin menggunakan io objek nanti). Cara saya melakukan ini sekarang:

// sockets.js
var socketio = require('socket.io')

module.exports.listen = function(app){
    io = socketio.listen(app)

    users = io.of('/users')
    users.on('connection', function(socket){
        socket.on ...
    })

    return io
}

Kemudian setelah membuat server app:

// main.js
var io = require('./lib/sockets').listen(app)

77
2018-03-25 02:42



saya akan melakukan sesuatu seperti ini.

app.js

var app = require('http').createServer(handler),
    sockets = require('./sockets'),
    fs = require('fs');

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

sockets.startSocketServer(app);
app.listen(80);

dan sockets.js

var socketio = require('socket.io'),
        io, clients = {};

module.exports = {

        startSocketServer: function (app) {
                io = socketio.listen(app);

                // configure
                io.configure('development', function () {
                        //io.set('transports', ['websocket', 'xhr-polling']);
                        //io.enable('log');
                });

                io.configure('production', function () {
                        io.enable('browser client minification');  // send minified client
                        io.enable('browser client etag');          // apply etag caching logic based on version number
                        io.set('log level', 1);                    // reduce logging
                        io.set('transports', [                     // enable all transports (optional if you want flashsocket)
                            'websocket'
                          , 'flashsocket'
                          , 'htmlfile'
                          , 'xhr-polling'
                          , 'jsonp-polling'
                        ]);
                });
                //

                io.sockets.on('connection', function (socket) {
                        console.log("new connection: " + socket.id);

                        socket.on('disconnect', function () {
                                console.log("device disconnected");

                        });

                        socket.on('connect_device', function (data, fn) {
                                console.log("data from connected device: " + data);
                                for (var col in data) {
                                        console.log(col + " => " + data[col]);
                                }


                        });
                });
        }
};

Saya hanya menyalin & menyisipkan beberapa kode lama saya - tidak benar-benar tahu apa yang berubah di versi terakhir dari socket.io, tetapi ini lebih tentang struktur daripada kode yang sebenarnya.

dan saya hanya akan menggunakan 2 file untuk tujuan Anda, bukan 3. ketika Anda berpikir tentang membaginya lebih lanjut, mungkin satu file lain untuk rute yang berbeda ...

semoga ini membantu.


5
2018-03-19 15:57



Saya memiliki celah di ini juga dan saya cukup senang dengan hasilnya. Periksa https://github.com/hackify/hackify-server untuk kode sumber.


1
2017-07-10 22:08



Saya punya solusi lain. Anda dapat menggunakan require.js membuat modul dan meneruskan "aplikasi" sebagai argumen. Dalam modul Anda dapat memulai socket.io dan mengatur soket Anda.

app.js:

  var requirejs = require('requirejs');

  requirejs.config({
      baseUrl: './',
      nodeRequire: require
  });

  requirejs(['sockets'], function(sockets) {

    var app = require('http').createServer()
      , fs  = require('fs')
      , io  = sockets(app);

      // do something
      // add more sockets here using "io" resource

  });

Di dalam Anda socket.js modul Anda dapat melakukan sesuatu seperti ini:

  define(['socket.io'], function(socket){
    return function(app){
      var server = app.listen(3000) 
        , io     = socket.listen(server);

      io.sockets.on('connection', function (socket) {
        console.log('connected to socket');

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

        // more more more

      });

      return io;
    }
  });

Saya harap dapat membantu Anda dengan kontribusi saya.


0
2017-12-26 23:32