bluefire
Version:
Lightweight tcp framework
164 lines (123 loc) • 5.13 kB
text/coffeescript
try
Session = require("#{global.CurrentWorkingDirectory}/sessions/Session")
catch exception
Session = require("../session/Session")
Parser = require("../parser/Parser")
Router = require("../routing/Router")
Configuration = require("../config/Configuration")
Protocol = require("./Protocol")
EventEmitter = require("events").EventEmitter
###
Main server class which stores tcp connection, packets and parser
###
module.exports = class Connection extends EventEmitter
constructor: () ->
= []
# add server as service
Injector.addService("$connection", @)
= new Protocol() # create new protocol and add it to injector
Injector.addService("$protocol", )
# @property [Object] Parser instance
= new Parser() # require default parsr
.initialize() # initialize with defaults
= new Router()
Injector.addService("$router", )
if
= new(require("./TCPAcceptor"))
else
= new(require("./TCPConnector"))
install: (, routerConfiguration, callback) =>
# create parser and add packets
parserModuleName = .get("parser")
if parserModuleName? and parserModuleName isnt "packetbuddy"
(parserModuleName, .get(parserModuleName))
else if parserModuleName is "packetbuddy"
(, .get(parserModuleName))
# if no parser is defined in the configuration, defaukt will be used instead
try
packets = require("#{global.CurrentWorkingDirectory}/configs/packets")
if packets.Head? # register head if found in collection
.getHead().add(packets.Head)
# register all packets
for name, packetStructure of packets.ServerPackets
(name, true, packetStructure)
for name, packetStructure of packets.ClientPackets
(name, false, packetStructure)
catch exception # this is optional, use debug mode to log
# console.log "Packet install exception: #{exception}"
# no packets found
# install router
.install(routerConfiguration)
callback(null)
###
Adds given packet to the parser.
###
packet: (name, isServerPacket, structure) ->
.packet(name, isServerPacket, structure).add(structure)
###
Adds structure to the parser head packet
structure [Object] structure of the head packet
[Packet] current head packet
###
headPacket: (structure) ->
.getHead().add(structure)
return .getHead()
###
Replaces the current packet parser with new module
module [String|Parser] name of module to be set as a parser
###
setParser: (module, options = {}) =>
if typeof module is "string"
ParserModule = require(module)
= new ParserModule()
else
= module
args = Injector.resolve(.initialize, options)
.initialize(args...)
###
Starts to listen on given port (by argument paseed or configuration)
port [Integer] port to listen on. This will override local configuration
address [String] address to connect to if is client
###
run: (port = null, address = null) =>
if not ? # repair missing configuration (no install)
= new Configuration
# override the configuration port if other port is specified (non structured approach)
if port isnt null then .add("port", port)
if address isnt null then .add("address", address)
.on "connect",
runOptions = Injector.resolve(.run, .data)
.run(runOptions...)
###
Stops current connection system, disabling it to send or receive
data. Connection must be then established once more to get working
###
stop: () ->
.stop()
removeSession: (session) =>
index = .indexOf(session)
if index isnt -1
.splice(index, 1)
else
console.log("Cannot remove given session, possible leak!")
_onConnect: (socket) =>
do (socket) =>
session = new Session
session.initialize(socket, )
# save session into the array
.push(session)
.initializeSession(session) # initialize session for current protocol
("connect", session) # emit new connection
session.onConnect() if session.onConnect?
socket.on "data", (buffer) =>
.receive buffer, session, (data) =>
.parse(data).then (packet) =>
.call(packet.name, session, packet.data)
socket.on "close", () =>
session.removeAllTasks()
(session) # remove current session from storage
session.onDisconnect()
("close", session)
socket.on "error", () =>
console.log("Unexpected error on connected socket, disconnecting")
(session)