簡體   English   中英

使用Express 4模塊化Socket.io

[英]Modularizing Socket.io with Express 4

我正在嘗試模塊化我的應用程序文件,而Socket.io出現問題。 我想在我的routes.js使用io。 像這樣:

var router = require('express').Router();
var io     = require('./sockets/my-io');

router.get('/', function(req, res) {
  io.emit('request-detected');
});

module.exports = router;

但是我不能這樣做,因為socket.io需要應用服務器,並且當我位於routes.js文件中時,應用服務器還沒有在偵聽或正在導出。

您能給我一個解決方案,還是任何其他解決此問題的方法?

這是我所擁有的,如果可能,我想保留文件結構

app.js

var app = require('express')();
var routes = require('./routes');

/* ... */

app.use('/contacts', routes);

module.exports = app;

斌/ WWW

#!/usr/bin/env node

var app = require('../wallet');

var server = app.listen(port, function() {
  debug('Express is listening o port ' + port);
});

routes.js

var router = require('express').Router();

router.get('/', function(req, res) {
  console.log('hey');
});

module.exports = router;

您可以通過將io變量傳遞給routes模塊來實現。

斌/ WWW

#!/usr/bin/env node

var app = require('./app');

var server = app.listen(3000, function() {
    console.log('Express is listening on port 3000');
}); // start the server

var socket = require('./socket')(server); // require socket.io code
var routes = require('./routes')(socket); // require routes

app.use('/', routes);

app.js

var express = require('express');

var app = express();

app.use(express.static(__dirname + '/public'));
app.set('views engine', 'ejs');
app.set('views', __dirname + '/');

module.exports = app;

socket.js

var socketio = require('socket.io');
function init(server) {
    var io = socketio(server);
    io.on('connection', function (socket) {
        console.log("socket connected");
        socket.on('newEvent', function (data) {
            console.log(data);
        });
    });
    return io;
}

module.exports = init;

routes.js

var express = require('express');
var route = express.Router();

function init(io) {
    route.get('/', function (req, res) {
        res.render('index.ejs', {});
        setTimeout(function() {io.emit('newEvent', {message: "Hi from the server"})}, 2000);
    });
    return route;
}
module.exports = init;

上面的代碼為我工作。 但是,我不確定您為什么要這樣做。

在路由器內部,您仍然可以完全控制要通過html發送給用戶的內容,因此您可以直接將數據添加到html中。 socket.io的想法是,一旦客戶端加載了html並使用socket.io建立了到服務器的連接,便可以在客戶端和客戶端之間發送數據。

如您在routes.js ,我不得不向發射添加超時。 這是因為套接字事件將在瀏覽器重新加載頁面之前發出。 就我而言,瀏覽器記錄了事件,然后立即刷新,丟失了您剛剛發送的數據。

另一個問題是,您對請求該頁面的客戶端套接字一無所知,因為該客戶端尚未連接。 這意味着調用io.emit()會將事件發送到所有連接的套接字。

就像我說的,這實際上取決於您到底想做什么。

編輯:

您可以使用socket.io來代替使用ajax更新聯系人。

socket.js

var socketio = require('socket.io');
function init(server) {
    var io = socketio(server);
    io.on('connection', function (socket) {
        console.log("socket connected");
        socket.on('newContact', function (data, callback) {
            // add data.contactName to db

            // after adding something, you use the callback to
            // send the added data back to the client

            // callback(newContact);
        });
    });
    return io;
}

module.exports = init;

的index.html

<script type="text/javascript" >
    var socket = io();
    // call this emit when the user wants to add a contact
    socket.emit('newContact', {contactName: name}, function(newContact) {
        // here you will get the result from the server and you can
        // update the html with jquery for example
    });
</script>

如果我正確理解您的問題,也許您可​​以嘗試這種方式。

在你的routes.js文件中

var app    = require('./app');
var server = require('http').createServer(app);
var io     = require('./sockets/my-io')(server);
var route  = app.Router();

在您的app.js文件中

var port = process.env.PORT || 3000;

app.listen(port,function(){ 
    console.log('server on port ' + port)
})

暫無
暫無

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

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