mirror of
https://github.com/openstf/stf
synced 2025-10-05 02:29:26 +02:00
125 lines
3.4 KiB
JavaScript
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()
|
|
})
|
|
})
|
|
})
|