1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-05 02:29:26 +02:00
OpenSTF/lib/units/device/plugins/vnc/index.js
2015-09-14 18:00:17 +09:00

125 lines
3.4 KiB
JavaScript

var net = require('net')
var util = require('util')
var syrup = require('stf-syrup')
var Promise = require('bluebird')
var uuid = require('node-uuid')
var jpeg = require('jpeg-js')
var logger = require('../../../../util/logger')
var lifecycle = require('../../../../util/lifecycle')
var VncServer = require('./util/server')
var VncConnection = require('./util/connection')
module.exports = syrup.serial()
.dependency(require('../screen/stream'))
.define(function(options, screenStream) {
var log = logger.createLogger('device:plugins:vnc')
function createServer() {
log.info('Starting VNC server on port %d', options.vncPort)
var vnc = new VncServer(net.createServer({
allowHalfOpen: true
}))
var listeningListener, errorListener
return new Promise(function(resolve, reject) {
listeningListener = function() {
return resolve(vnc)
}
errorListener = function(err) {
return reject(err)
}
vnc.on('listening', listeningListener)
vnc.on('error', errorListener)
vnc.listen(options.vncPort)
})
.finally(function() {
vnc.removeListener('listening', listeningListener)
vnc.removeListener('error', errorListener)
})
}
return createServer()
.then(function(vnc) {
vnc.on('connection', function(conn) {
var id = util.format('vnc-%s', uuid.v4())
var connState = {
lastFrame: null
, lastFrameTime: null
, frameWidth: 0
, frameHeight: 0
, sentFrameTime: null
, updateRequests: 0
}
function vncStartListener(frameProducer) {
return new Promise(function(resolve/*, reject*/) {
connState.frameWidth = frameProducer.banner.virtualWidth
connState.frameHeight = frameProducer.banner.virtualHeight
resolve()
})
}
function vncFrameListener(frame) {
return new Promise(function(resolve/*, reject*/) {
connState.lastFrame = frame
connState.lastFrameTime = Date.now()
maybeSendFrame()
resolve()
})
}
function maybeSendFrame() {
if (!connState.updateRequests) {
return
}
if (!connState.lastFrame) {
return
}
if (connState.lastFrameTime === connState.sentFrameTime) {
return
}
var decoded = jpeg.decode(connState.lastFrame)
conn.writeFramebufferUpdate([{
xPosition: 0
, yPosition: 0
, width: connState.frameWidth
, height: connState.frameHeight
, encodingType: VncConnection.ENCODING_RAW
, data: decoded.data
}])
connState.updateRequests = 0
connState.sentFrameTime = connState.lastFrameTime
}
screenStream.broadcastSet.insert(id, {
onStart: vncStartListener
, onFrame: vncFrameListener
})
conn.on('fbupdaterequest', function() {
connState.updateRequests += 1
maybeSendFrame()
})
conn.on('close', function() {
screenStream.broadcastSet.remove(id)
})
})
lifecycle.observe(function() {
vnc.close()
})
})
})