【问题标题】:Node.JS + Socket.io, moving socket event handlers to external module?Node.JS + Socket.io,将套接字事件处理程序移动到外部模块?
【发布时间】:2015-12-27 22:39:00
【问题描述】:

我有一个这样的 server.js 文件:

var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    mongoose = require('mongoose'),
    bodyParser = require('body-parser'),
    apiRouter = require('./app/routes/api.js'),
    io = require('socket.io')(server),
    socketEvents = require('./app/modules/socketEvents.js')(io);

//Clears Node Console.
process.stdout.write('\033c');
console.log('Server starting!');

socketEvents.attachEventHandlers();

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/api', apiRouter);
app.use(express.static('public'));

app.use('*', function(req, res, next) {
    //All requests return single page angular application.
    res.sendFile(__dirname + '/public/index.html');
});

mongoose.connect('localhost', 'triviaattack', function(err) {
    if (err) {
        console.log('An error occured when connecting to the MongoDB Database');
        throw err;
    }
});

server.listen(1337);

还有socketEvents.js

module.exports = function(io) {

    return {
        attachEventHandlers: function() {

            io.on('connection', function(socket) {

                console.log('client connected');

                socket.on('joinMatchMaking', function(data) {
                    //Every time a player joins the matchmaking queue, check if a game can be created.
                    matchMakingQueue.push(data);
                    var matchedPlayers = [];
                    for (i = 0; i < matchMakingQueue.length; i++) {
                        switch (data.gameType) {
                            case '1v1':
                                matchedPlayers.push(matchMakingQueue[i].username);
                                if (matchedPlayers.length == 2) {
                                    socket.emit('matchFound', {players: matchedPlayers});
                                } 
                                console.log('user joined 1v1 queue');
                            case '2v2':
                                matchedPlayers.push(matchMakingQueue[i].username);
                                if (matchedPlayers.length == 4) {
                                    socket.emit('matchFound', {players: matchedPlayers});
                                } 
                                console.log('user joined 2v2 queue');
                        }
                    }
                    console.log(data.username + ' joined the ' + data.gameType + ' matchmaking queue');
                    console.log('users in queue: ' + matchMakingQueue.length);
                });

                socket.on('leaveMatchMaking', function(username) {
                    matchMakingQueue.splice(matchMakingQueue.indexOf(username), 1);
                    console.log(username + ' left matchmaking queue.');
                    console.log('users in queue: ' + matchMakingQueue.length);
                });

            });

        console.log('events attached');

        }
    }

};

当我在浏览器中加载我的网站时,没有调用 io.on('connection), function () {...}) 事件处理程序,它应该在客户端连接时输出一条 console.log 消息。我想将我的 socket.io 事件保留在我的主 server.js 文件之外,因为它们会很多,我想将它们分离到它们自己的模块中。

【问题讨论】:

    标签: javascript node.js sockets socket.io


    【解决方案1】:

    你需要在 html 文件中有一些套接字代码才能连接.. 你也可以包含它吗?

    【讨论】:

    • 嗨,这是我的错误。感谢您的回复,我错过了发出“连接”的客户端代码,哎呀:(
    • 将此添加到我的 index.html
    【解决方案2】:

    我通过将所有套接字事件填充到中间件中来做到这一点:

    var io = require('socket.io');
    // listen stuff
    var SocketEvents = require('./socket-events.js')(io);
    io.use(SocketEvents);
    

    ...然后在socket-events.js 中类似:

    module.exports = function(io) {
        return function(socket, next) {
            // do stuff
            return next();
        }
    }
    

    我应该补充一点,在这种情况下,on("connection") 侦听器似乎不是必需的,因为每个中间件函数已经在每个传入的套接字连接上执行。

    【讨论】:

    • 您好,谢谢,与我尝试的方式相比,这样做的优势是什么?只是想知道,或者他们是否都实现了同样的目标。无论如何,我遇到的问题是未能包含客户端 io.emit('connection')...当我添加 到我的 index.html 就可以了
    • @David,我喜欢这种方法让我进一步划分功能的方式。如果我需要将每个套接字事件拆分到自己的文件中,这样做真的很容易。我在一个半完成的项目中有类似的东西,如果你愿意,我可以给你链接。
    • 当然,我想看看。使用我所做的方法,我将仅限于将所有事件保存在 1 个文件中?
    • 哦,不——一点也不。不过,我确实认为使用中间件更简洁。另一个好处是您可以将其他属性附加到套接字对象,然后这些属性可以在连续的中间件功能中使用 - 我不相信使用像您在这里得到的模块那样的情况。需要注意的是,中间件是连续调用的,因此它们的包含顺序很重要。
    • 我喜欢这种方法!这让我很容易理解。你可以看看我是如何使用它来分解我在my project 的服务器半部分的逻辑的。具体来说就是中间件目录。
    猜你喜欢
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多