UNPKG

expresser

Version:

A ready to use Node.js web app wrapper, built on top of Express.

117 lines (92 loc) 4.56 kB
# EXPRESSER SOCKETS # -------------------------------------------------------------------------- # Handles sockets communication using the module Socket.IO. # ATTENTION! The Sockets module is started automatically by the App module. # If you wish to disable it, set `Settings.sockets.enabled` to false. # <!-- # @see Settings.sockets # --> class Sockets lodash = require "lodash" logger = require "./logger.coffee" settings = require "./settings.coffee" # @property [Array] Holds a list of current event listeners. currentListeners: null # @property [Socket.IO Object] Exposes Socket.IO object to external modules. io: null # INIT # -------------------------------------------------------------------------- # Bind the Socket.IO object to the Express app. This will also set the counter # to increase / decrease when users connects or disconnects from the app. # @param [Object] options Sockets init options. # @option options [Object] server The Express server object to bind to. init: (options) => options = {server: options} if not options.server? @currentListeners = [] if not options.server? logger.error "Sockets.init", "App server is invalid. Abort!" return @io = require("socket.io") options.server # Listen to user connection count updates. @io.sockets.on "connection", (socket) => @io.emit "connection-count", @getConnectionCount() socket.on "disconnect", @onDisconnect # Bind all current event listeners. for listener in @currentListeners socket.on listener.key, listener.callback if listener? # EVENTS # ---------------------------------------------------------------------- # Emit the specified key and data to clients. # @param [String] key The event key. # @param [Object] data The JSON data to be sent out to clients. emit: (key, data) => if @io? @io.emit key, data logger.debug "Sockets.emit", key, JSON.stringify(data).length + " bytes" else logger.debug "Sockets.emit", key, "Sockets not initiated yet, abort!" # Listen to a specific event. If `onlyNewClients` is true then it won't listen to that particular # event from currently connected clients. # @param [String] key The event key. # @param [Method] callback The callback to be called when key is triggered. # @param [Boolean] onlyNewClients Optional, if true, listen to event only from new clients. listenTo: (key, callback, onlyNewClients) => return if not callback? onlyNewClients = false if not onlyNewClients? @currentListeners.push {key: key, callback: callback} if not onlyNewClients for key, socket of @io.sockets.connected socket.on key, callback logger.debug "Sockets.listenTo", key # Stops listening to the specified event key. # @param [String] key The event key. # @param [Object] callback The callback to stop triggering. stopListening: (key, callback) => for socketKey, socket of @io.sockets.connected if callback? socket.removeListener key, callback else socket.removeAllListeners key # Remove binding from the currentListeners collection. for listener in @currentListeners if listener.key is key and (listener.callback is callback or not callback?) listener = null logger.debug "Sockets.stopListening", key # Remove invalid and expired event listeners. compact: => @currentListeners = lodash.compact @currentListeners # HELPERS # ---------------------------------------------------------------------- # Get how many users are currenly connected to the app. getConnectionCount: => return Object.keys(@io.sockets.connected).length # When user disconnects, emit an event with the new connection count to all clients. onDisconnect: => count = @getConnectionCount() logger.debug "Sockets.onDisconnect", "New count: #{count}." # Singleton implementation # -------------------------------------------------------------------------- Sockets.getInstance = -> @instance = new Sockets() if not @instance? return @instance module.exports = exports = Sockets.getInstance()