Get rid of switch statements in favor of an EventEmitter-based router for message handling.

This commit is contained in:
Simo Kinnunen
2014-02-02 19:55:44 +09:00
parent ade611670e
commit 48d5648b9d
8 changed files with 224 additions and 188 deletions

View File

@@ -13,6 +13,7 @@ var split = require('split')
var logger = require('../util/logger')
var wire = require('../wire')
var wireutil = require('../util/wireutil')(wire)
var wirerouter = require('../wire/router')
var devutil = require('../util/devutil')
var pathutil = require('../util/pathutil')
var promiseutil = require('../util/promiseutil')
@@ -326,90 +327,86 @@ module.exports = function(options) {
selfDestruct()
})
sub.on('message', function(channel, data) {
var wrapper = wire.Envelope.decode(data)
channels.keepalive(channel)
switch (wrapper.type) {
case wire.MessageType.PROBE:
var message = wire.ProbeMessage.decode(wrapper.message)
push.send([channel,
wireutil.makeDeviceIdentityMessage(options.serial, identity)])
break
case wire.MessageType.GROUP:
var message = wire.GroupMessage.decode(wrapper.message)
, groupChannel = message.channel
if (devutil.matchesRequirements(identity, message.requirements)) {
channels.register(groupChannel, message.timeout)
log.info('Subscribing to group channel "%s"', groupChannel)
sub.subscribe(groupChannel)
push.send([groupChannel,
wireutil.makeJoinGroupMessage(options.serial)])
}
break
case wire.MessageType.UNGROUP:
var message = wire.UngroupMessage.decode(wrapper.message)
, groupChannel = message.channel
if (devutil.matchesRequirements(identity, message.requirements)) {
channels.unregister(groupChannel)
log.info('Unsubscribing from group channel "%s"', groupChannel)
sub.unsubscribe(groupChannel)
push.send([groupChannel,
wireutil.makeLeaveGroupMessage(options.serial)])
}
break
case wire.MessageType.SHELL_COMMAND:
var message = wire.ShellCommandMessage.decode(wrapper.message)
log.info('Running shell command "%s"', message.command.join(' '))
adb.shellAsync(options.serial, message.command)
.then(function(stream) {
var resolver = Promise.defer()
, seq = 0
sub.on('message', wirerouter()
.on(wire.MessageType.ProbeMessage, function(channel, message) {
push.send([channel,
wireutil.makeDeviceIdentityMessage(options.serial, identity)])
channels.keepalive(channel)
})
.on(wire.MessageType.GroupMessage, function(channel, message) {
var groupChannel = message.channel
if (devutil.matchesRequirements(identity, message.requirements)) {
channels.register(groupChannel, message.timeout)
log.info('Subscribing to group channel "%s"', groupChannel)
sub.subscribe(groupChannel)
push.send([groupChannel,
wireutil.makeJoinGroupMessage(options.serial)])
}
channels.keepalive(channel)
})
.on(wire.MessageType.UngroupMessage, function(channel, message) {
var groupChannel = message.channel
if (devutil.matchesRequirements(identity, message.requirements)) {
channels.unregister(groupChannel)
log.info('Unsubscribing from group channel "%s"', groupChannel)
sub.unsubscribe(groupChannel)
push.send([groupChannel,
wireutil.makeLeaveGroupMessage(options.serial)])
}
channels.keepalive(channel)
})
.on(wire.MessageType.ShellCommandMessage, function(channel, message) {
log.info('Running shell command "%s"', message.command.join(' '))
adb.shellAsync(options.serial, message.command)
.then(function(stream) {
var resolver = Promise.defer()
, seq = 0
function dataListener(chunk) {
push.send([message.channel,
wireutil.makeDeviceDataMessage(
options.serial
, seq++
, chunk
)])
}
function endListener() {
push.send([message.channel,
wireutil.makeDeviceDoneMessage(options.serial)])
resolver.resolve()
}
function errorListener(err) {
log.error('Shell command "%s" failed due to "%s"'
, message.command.join(' '), err.message)
resolver.reject(err)
push.send([message.channel,
wireutil.makeDeviceFailMessage(
options.serial
, err.message
)])
}
stream.on('data', dataListener)
stream.on('end', endListener)
stream.on('error', errorListener)
return resolver.promise.finally(function() {
stream.removeListener('data', dataListener)
stream.removeListener('end', endListener)
stream.removeListener('error', errorListener)
})
})
.error(function(err) {
log.error('Shell command "%s" failed due to "%s"'
, message.command.join(' '), err.message)
function dataListener(chunk) {
push.send([message.channel,
wire.makeDeviceFailMessage(options.serial, err.message)])
wireutil.makeShellCommandDataMessage(
options.serial
, seq++
, chunk
)])
}
function endListener() {
push.send([message.channel,
wireutil.makeShellCommandDoneMessage(options.serial)])
resolver.resolve()
}
function errorListener(err) {
log.error('Shell command "%s" failed due to "%s"'
, message.command.join(' '), err.message)
resolver.reject(err)
push.send([message.channel,
wireutil.makeShellCommandFailMessage(
options.serial
, err.message
)])
}
stream.on('data', dataListener)
stream.on('end', endListener)
stream.on('error', errorListener)
return resolver.promise.finally(function() {
stream.removeListener('data', dataListener)
stream.removeListener('end', endListener)
stream.removeListener('error', errorListener)
})
break
}
})
})
.error(function(err) {
log.error('Shell command "%s" failed due to "%s"'
, message.command.join(' '), err.message)
push.send([message.channel,
wire.makeShellCommandFailMessage(options.serial, err.message)])
})
channels.keepalive(channel)
})
.handler())
function poke() {
push.send([wireutil.global,