繁体   English   中英

如何使用socket.io在多个模块中定义侦听器

[英]How to define listeners in multiple modules with socket.io

半年前,我在node.js和socket.io中编写了一个多人游戏。 现在,我正在尝试对其进行改进,其中一项改进就是将代码分解为模块(顺便说一句,我正在使用expressjs 4.4和socket.io 1.0)。 我有一个播放器队列,该队列处理连接的播放器的顺序。 一切都进行得很顺利,直到我被socket.io卡住了:我想处理玩家队列中的(断开连接)侦听器,而我想将所有与游戏相关的侦听器放入我的游戏模块中。 我尝试了几件事,包括使用模块中的socket.io以及在模块 之间传递Socket.IO套接字的正确方法是什么? 我都没有上班。 目前,我正在通过以下方式传递io对象:

io = require("socket.io")(server);

我想念什么吗?

我的代码:

PlayerManager.js

var log = require("npmlog"),
    Player = require("./Model/Player").Player;

var playerIo;

var PlayerManager = (function() {
    var self;

    function PlayerManager(eventEmitter, io) {
        log.info("PlayerManager", "loading PlayerManager");

        self = this;

        this.eventEmitter = eventEmitter;
        this.io = io;
        this.playerQueue = [];
        this.players = [];

        this.setSocketListeners();
    }

    PlayerManager.prototype.setSocketListeners = function() {
        log.info("PlayerManager", "loading SocketListeners");

        playerIo = this.io.of("/player").on("connection", function(socket) {
            log.info("PlayerManager", "Player " + socket.id + " has connected");

            socket.on("disconnect", function() {
                log.info("PlayerManager", "Player " + socket.id + " has disconnected.");

                self.removePlayer(socket.id);
            });

            self.addPlayer(new Player(socket));
        });
    };

    PlayerManager.prototype.addPlayer = function(player) {
        log.info("PlayerManager", "Pushing Player " + player.socket.id + " to Queue. Current position: " + this.playerQueue.length);

        this.playerQueue.push(player);
    };

    PlayerManager.prototype.removePlayer = function(id) {
        log.info("PlayerManager", "Removing Player " + id + " from Queue");

        var player = this.getPlayerById(id);

        if (!player) {
            return;
        }

        this.playerQueue.splice(this.playerQueue.indexOf(player), 1);
    };

    PlayerManager.prototype.getPlayers = function() {
        log.info("PlayerManager", "Choosing players (length of queue: " + this.playerQueue.length + ")");

        this.players = [];

        if (this.playerQueue.length >= 1) { //should be changed to 2 in PROD
            var player;

            for (var i = 0; i < 4; ++i) {
                player = this.playerQueue.shift();

                if (player !== undefined && !player.socket.disconnected) {
                    player.socket.join("players");
                    this.players.push(player);
                }
            }

            return this.players;
        } else {
            return false;
        }
    };

    PlayerManager.prototype.onGameFinished = function() {
        var player;

        while (this.players && this.players.length > 0) {
            player = this.players.shift();

            player.socket.leave("players");

            log.info("GameManager", "players size: " + self.players.length);
        }
    };

    PlayerManager.prototype.getPlayerById = function(id) {
        for (var i = 0; i < this.playerQueue.length; ++i) {
            if (this.playerQueue[i].socket.id === id) {
                return this.playerQueue[i];
            }
        }

        return false;
    };

    return PlayerManager;
})();

exports = module.exports = PlayerManager;

Game.js

var log = require("npmlog");
var config = require("./config");
var Duck = require("./Model/Duck").Duck;

var Game = (function() {
    var self;

    function Game(eventEmitter, io, players) {
        log.info("Game", "loading ...");

        self = this;

        this.io = io;
        this.eventEmitter = eventEmitter;
        this.players = players;

        setInterval(function() {
            self.io.to("players").emit("blub");
        });

        // ...

    return Game;
})();

exports = module.exports = Game;

为了完整性:

index.js (客户端)

define(["socketio"], function(io) {
    var socket = io("/player");

    socket.on("blub", function() {
        console.log("blub");
    });

    setInterval(function() {
        socket.emit("blub");
    }, 1000);
});

一年后,是时候清理并分享我在那段时期获得的见解了。

将与socket.io相关的代码散布在整个项目中是不好的设计(或与此有关的任何其他库中的代码)。 如果必须更改包装器库,则必须在代码库中的许多位置进行更改。 更好的方法是将socket.io的使用限制为薄薄的层,在薄层中完成与Websocket的所有通信。 从那里开始,您将使用另一层消息传递:您自己的消息传递。 Node.js自己的EventEmitter是您完成工作所需的一切。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM