1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-05 19:42:01 +02:00

Hopefully fix occasional errors when trying to send an initial banner to a frame client. After looking through ws' source, the most likely reason seems to be that the websocket is in CLOSING state. Even if not, we should get a bit more useful log output this time.

This commit is contained in:
Simo Kinnunen 2015-07-01 12:46:36 +09:00
parent 02779f648d
commit 9f627cb129
2 changed files with 57 additions and 9 deletions

View file

@ -2,7 +2,7 @@ var util = require('util')
var Promise = require('bluebird') var Promise = require('bluebird')
var syrup = require('stf-syrup') var syrup = require('stf-syrup')
var WebSocketServer = require('ws').Server var WebSocket = require('ws')
var uuid = require('node-uuid') var uuid = require('node-uuid')
var EventEmitter = require('eventemitter3').EventEmitter var EventEmitter = require('eventemitter3').EventEmitter
var split = require('split') var split = require('split')
@ -400,7 +400,7 @@ module.exports = syrup.serial()
function createServer() { function createServer() {
log.info('Starting WebSocket server on port %d', screenOptions.publicPort) log.info('Starting WebSocket server on port %d', screenOptions.publicPort)
var wss = new WebSocketServer({ var wss = new WebSocket.Server({
port: screenOptions.publicPort port: screenOptions.publicPort
, perMessageDeflate: false , perMessageDeflate: false
}) })
@ -448,19 +448,59 @@ module.exports = syrup.serial()
, JSON.stringify(frameProducer.banner) , JSON.stringify(frameProducer.banner)
) )
broadcastSet.values().forEach(function(ws) { broadcastSet.keys().forEach(function(id) {
ws.send(message) var ws = broadcastSet.get(id)
switch (ws.readyState) {
case WebSocket.OPENING:
// This should never happen.
log.warn('Unable to send banner to OPENING client "%s"', id)
break
case WebSocket.OPEN:
// This is what SHOULD happen.
ws.send(message)
break
case WebSocket.CLOSING:
// Ok, a 'close' event should remove the client from the set
// soon.
break
case WebSocket.CLOSED:
// This should never happen.
log.warn('Unable to send banner to CLOSED client "%s"', id)
broadcastSet.remove(id)
break
}
}) })
}) })
frameProducer.on('readable', function next() { frameProducer.on('readable', function next() {
var frame var frame
if ((frame = frameProducer.nextFrame())) { if ((frame = frameProducer.nextFrame())) {
Promise.settle([broadcastSet.values().map(function(ws) { Promise.settle([broadcastSet.keys().map(function(id) {
return new Promise(function(resolve/*, reject*/) { return new Promise(function(resolve, reject) {
ws.send(frame, { var ws = broadcastSet.get(id)
binary: true switch (ws.readyState) {
}, resolve) case WebSocket.OPENING:
// This should never happen.
return reject(new Error(util.format(
'Unable to send frame to OPENING client "%s"', id)))
case WebSocket.OPEN:
// This is what SHOULD happen.
ws.send(frame, {
binary: true
}, function(err) {
return err ? reject(err) : resolve()
})
return
case WebSocket.CLOSING:
// Ok, a 'close' event should remove the client from the set
// soon.
return
case WebSocket.CLOSED:
// This should never happen.
broadcastSet.remove(id)
return reject(new Error(util.format(
'Unable to send frame to CLOSED client "%s"', id)))
}
}) })
})]).then(next) })]).then(next)
} }

View file

@ -37,4 +37,12 @@ BroadcastSet.prototype.values = function() {
}, this) }, this)
} }
BroadcastSet.prototype.keys = function() {
return Object.keys(this.set)
}
BroadcastSet.prototype.get = function(id) {
return this.set[id]
}
module.exports = BroadcastSet module.exports = BroadcastSet