mirror of
				https://github.com/amitbet/vncproxy.git
				synced 2025-11-04 11:44:02 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			1.01
			...
			keyframes_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					1bce301125 | ||
| 
						 | 
					f19a75749b | ||
| 
						 | 
					02dde77daa | ||
| 
						 | 
					b46f708726 | ||
| 
						 | 
					f298567976 | 
@@ -16,13 +16,17 @@ An RFB proxy, written in go that can save and replay FBS files
 | 
				
			|||||||
    - VineVnc(server)
 | 
					    - VineVnc(server)
 | 
				
			||||||
    - TigerVnc(client)
 | 
					    - TigerVnc(client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Usage:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Executables (see releases)
 | 
					### Executables (see releases)
 | 
				
			||||||
* proxy - the actual recording proxy, supports listening to tcp & ws ports and recording traffic to fbs files
 | 
					* proxy - the actual recording proxy, supports listening to tcp & ws ports and recording traffic to fbs files
 | 
				
			||||||
* recorder - connects to a vnc server as a client and records the screen
 | 
					* recorder - connects to a vnc server as a client and records the screen
 | 
				
			||||||
* player - a toy player that will replay a given fbs file to all incoming connections
 | 
					* player - a toy player that will replay a given fbs file to all incoming connections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Usage:
 | 
				
			||||||
 | 
					    recorder -recDir=./recording.rbs -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@
 | 
				
			||||||
 | 
					    player -fbsFile=./myrec.fbs -tcpPort=5905
 | 
				
			||||||
 | 
					    proxy -recDir=./recordings/ -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ -tcpPort=5903 -vncPass=@!@!@!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Code usage examples
 | 
					### Code usage examples
 | 
				
			||||||
* player/main.go (fbs recording vnc client) 
 | 
					* player/main.go (fbs recording vnc client) 
 | 
				
			||||||
    * Connects as client, records to FBS file
 | 
					    * Connects as client, records to FBS file
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								build.sh
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
				
			|||||||
sum="sha1sum"
 | 
					sum="sha1sum"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# VERSION=`date -u +%Y%m%d`
 | 
					# VERSION=`date -u +%Y%m%d`
 | 
				
			||||||
VERSION="v1.01"
 | 
					VERSION="v1.02"
 | 
				
			||||||
LDFLAGS="-X main.VERSION=$VERSION -s -w"
 | 
					LDFLAGS="-X main.VERSION=$VERSION -s -w"
 | 
				
			||||||
GCFLAGS=""
 | 
					GCFLAGS=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package logger
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var simpleLogger = SimpleLogger{LogLevelDebug}
 | 
					var simpleLogger = SimpleLogger{LogLevelInfo}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Logger interface {
 | 
					type Logger interface {
 | 
				
			||||||
	Debug(v ...interface{})
 | 
						Debug(v ...interface{})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,7 @@ func main() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	url := "http://localhost:" + *wsPort + "/"
 | 
						url := "http://0.0.0.0:" + *wsPort + "/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if *tcpPort != "" && *wsPort != "" {
 | 
						if *tcpPort != "" && *wsPort != "" {
 | 
				
			||||||
		logger.Infof("running two listeners: tcp port: %s, ws url: %s", *tcpPort, url)
 | 
							logger.Infof("running two listeners: tcp port: %s, ws url: %s", *tcpPort, url)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										199
									
								
								player/rfb-reader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								player/rfb-reader.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
				
			|||||||
 | 
					package player
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"vncproxy/common"
 | 
				
			||||||
 | 
						"vncproxy/encodings"
 | 
				
			||||||
 | 
						"vncproxy/logger"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RfbReader struct {
 | 
				
			||||||
 | 
						reader           io.Reader
 | 
				
			||||||
 | 
						buffer           bytes.Buffer
 | 
				
			||||||
 | 
						currentTimestamp int
 | 
				
			||||||
 | 
						pixelFormat      *common.PixelFormat
 | 
				
			||||||
 | 
						encodings        []common.IEncoding
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************
 | 
				
			||||||
 | 
					** RFB File documentation:
 | 
				
			||||||
 | 
					** Sections:
 | 
				
			||||||
 | 
					** 0. header:
 | 
				
			||||||
 | 
						* index seek position
 | 
				
			||||||
 | 
						*
 | 
				
			||||||
 | 
					** 1. init message
 | 
				
			||||||
 | 
					** 2. content
 | 
				
			||||||
 | 
						* frame message:
 | 
				
			||||||
 | 
							* size, timestamp, type, content
 | 
				
			||||||
 | 
					** 3. index:
 | 
				
			||||||
 | 
						* each frame message start position, full/incremental, timestamp
 | 
				
			||||||
 | 
						*
 | 
				
			||||||
 | 
					***************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rfb *RfbReader) CurrentTimestamp() int {
 | 
				
			||||||
 | 
						return rfb.currentTimestamp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rfb *RfbReader) Read(p []byte) (n int, err error) {
 | 
				
			||||||
 | 
						if rfb.buffer.Len() < len(p) {
 | 
				
			||||||
 | 
							seg, err := rfb.ReadSegment()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logger.Error("rfbReader.Read: error reading rfbsegment: ", err)
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rfb.buffer.Write(seg.bytes)
 | 
				
			||||||
 | 
							rfb.currentTimestamp = int(seg.timestamp)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return rfb.buffer.Read(p)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rfb *RfbReader) CurrentPixelFormat() *common.PixelFormat { return rfb.pixelFormat }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//func (rfb *rfbReader) CurrentColorMap() *common.ColorMap       { return &common.ColorMap{} }
 | 
				
			||||||
 | 
					func (rfb *RfbReader) Encodings() []common.IEncoding { return rfb.encodings }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewRfbReader(rfbFile string) (*RfbReader, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reader, err := os.OpenFile(rfbFile, os.O_RDONLY, 0644)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("NewrfbReader: can't open rfb file: ", rfbFile)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &RfbReader{reader: reader,
 | 
				
			||||||
 | 
							encodings: []common.IEncoding{
 | 
				
			||||||
 | 
								&encodings.CopyRectEncoding{},
 | 
				
			||||||
 | 
								&encodings.ZLibEncoding{},
 | 
				
			||||||
 | 
								&encodings.ZRLEEncoding{},
 | 
				
			||||||
 | 
								&encodings.CoRREEncoding{},
 | 
				
			||||||
 | 
								&encodings.HextileEncoding{},
 | 
				
			||||||
 | 
								&encodings.TightEncoding{},
 | 
				
			||||||
 | 
								&encodings.TightPngEncoding{},
 | 
				
			||||||
 | 
								&encodings.EncCursorPseudo{},
 | 
				
			||||||
 | 
								&encodings.RawEncoding{},
 | 
				
			||||||
 | 
								&encodings.RREEncoding{},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rfb *RfbReader) ReadStartSession() (*common.ServerInit, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						initMsg := common.ServerInit{}
 | 
				
			||||||
 | 
						reader := rfb.reader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var framebufferWidth uint16
 | 
				
			||||||
 | 
						var framebufferHeight uint16
 | 
				
			||||||
 | 
						var SecTypeNone uint32
 | 
				
			||||||
 | 
						//read rfb header information (the only part done without the [size|data|timestamp] block wrapper)
 | 
				
			||||||
 | 
						//.("rfb 001.000\n")
 | 
				
			||||||
 | 
						bytes := make([]byte, 12)
 | 
				
			||||||
 | 
						_, err := reader.Read(bytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init message - rfb file Version:", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read the version message into the buffer so it will be written in the first rbs block
 | 
				
			||||||
 | 
						//RFB 003.008\n
 | 
				
			||||||
 | 
						bytes = make([]byte, 12)
 | 
				
			||||||
 | 
						_, err = rfb.Read(bytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - RFB Version: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//push sec type and fb dimensions
 | 
				
			||||||
 | 
						binary.Read(rfb, binary.BigEndian, &SecTypeNone)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - SecType: ", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read frame buffer width, height
 | 
				
			||||||
 | 
						binary.Read(rfb, binary.BigEndian, &framebufferWidth)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - FBWidth: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						initMsg.FBWidth = framebufferWidth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						binary.Read(rfb, binary.BigEndian, &framebufferHeight)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - FBHeight: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						initMsg.FBHeight = framebufferHeight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read pixel format
 | 
				
			||||||
 | 
						pixelFormat := &common.PixelFormat{}
 | 
				
			||||||
 | 
						binary.Read(rfb, binary.BigEndian, pixelFormat)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - Pixelformat: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						initMsg.PixelFormat = *pixelFormat
 | 
				
			||||||
 | 
						//read padding
 | 
				
			||||||
 | 
						bytes = make([]byte, 3)
 | 
				
			||||||
 | 
						rfb.Read(bytes)
 | 
				
			||||||
 | 
						rfb.pixelFormat = pixelFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read desktop name
 | 
				
			||||||
 | 
						var desknameLen uint32
 | 
				
			||||||
 | 
						binary.Read(rfb, binary.BigEndian, &desknameLen)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - deskname Len: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						initMsg.NameLength = desknameLen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bytes = make([]byte, desknameLen)
 | 
				
			||||||
 | 
						rfb.Read(bytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: error reading rbs init - desktopName: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						initMsg.NameText = bytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &initMsg, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rfb *RfbReader) ReadSegment() (*FbsSegment, error) {
 | 
				
			||||||
 | 
						reader := rfb.reader
 | 
				
			||||||
 | 
						var bytesLen uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read length
 | 
				
			||||||
 | 
						err := binary.Read(reader, binary.BigEndian, &bytesLen)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadStartSession: read len, error reading rbs file: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						paddedSize := (bytesLen + 3) & 0x7FFFFFFC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read bytes
 | 
				
			||||||
 | 
						bytes := make([]byte, paddedSize)
 | 
				
			||||||
 | 
						_, err = reader.Read(bytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadSegment: read bytes, error reading rbs file: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//remove padding
 | 
				
			||||||
 | 
						actualBytes := bytes[:bytesLen]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//read timestamp
 | 
				
			||||||
 | 
						var timeSinceStart uint32
 | 
				
			||||||
 | 
						binary.Read(reader, binary.BigEndian, &timeSinceStart)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("rfbReader.ReadSegment: read timestamp, error reading rbs file: ", err)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//timeStamp := time.Unix(timeSinceStart, 0)
 | 
				
			||||||
 | 
						seg := &FbsSegment{bytes: actualBytes, timestamp: timeSinceStart}
 | 
				
			||||||
 | 
						return seg, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -42,8 +42,8 @@ func main() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proxy := &proxy.VncProxy{
 | 
						proxy := &proxy.VncProxy{
 | 
				
			||||||
		WsListeningUrl:   "http://localhost:" + string(*wsPort) + "/", // empty = not listening on ws
 | 
							WsListeningUrl:   "http://0.0.0.0:" + string(*wsPort) + "/", // empty = not listening on ws
 | 
				
			||||||
		RecordingDir:     *recordDir,                                  //"/Users/amitbet/vncRec",                     // empty = no recording
 | 
							RecordingDir:     *recordDir,                                //"/Users/amitbet/vncRec",                     // empty = no recording
 | 
				
			||||||
		TcpListeningUrl:  tcpUrl,
 | 
							TcpListeningUrl:  tcpUrl,
 | 
				
			||||||
		ProxyVncPassword: *vncPass, //empty = no auth
 | 
							ProxyVncPassword: *vncPass, //empty = no auth
 | 
				
			||||||
		SingleSession: &proxy.VncSession{
 | 
							SingleSession: &proxy.VncSession{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,15 +6,15 @@ func TestProxy(t *testing.T) {
 | 
				
			|||||||
	//create default session if required
 | 
						//create default session if required
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proxy := &VncProxy{
 | 
						proxy := &VncProxy{
 | 
				
			||||||
		WsListeningUrl:  "http://localhost:7777/", // empty = not listening on ws
 | 
							WsListeningUrl:  "http://0.0.0.0:7778/", // empty = not listening on ws
 | 
				
			||||||
		RecordingDir:    "/Users/amitbet/vncRec",  // empty = no recording
 | 
							RecordingDir:    "d:\\",                 // empty = no recording
 | 
				
			||||||
		TcpListeningUrl: ":5904",
 | 
							TcpListeningUrl: ":5904",
 | 
				
			||||||
		//recordingDir:          "C:\\vncRec", // empty = no recording
 | 
							//RecordingDir:          "C:\\vncRec", // empty = no recording
 | 
				
			||||||
		ProxyVncPassword: "1234", //empty = no auth
 | 
							ProxyVncPassword: "1234", //empty = no auth
 | 
				
			||||||
		SingleSession: &VncSession{
 | 
							SingleSession: &VncSession{
 | 
				
			||||||
			TargetHostname: "localhost",
 | 
								TargetHostname: "192.168.1.101",
 | 
				
			||||||
			TargetPort:     "5903",
 | 
								TargetPort:     "5901",
 | 
				
			||||||
			TargetPassword: "Ch_#!T@8",
 | 
								TargetPassword: "123456",
 | 
				
			||||||
			ID:             "dummySession",
 | 
								ID:             "dummySession",
 | 
				
			||||||
			Status:         SessionStatusInit,
 | 
								Status:         SessionStatusInit,
 | 
				
			||||||
			Type:           SessionTypeRecordingProxy,
 | 
								Type:           SessionTypeRecordingProxy,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,7 +67,11 @@ func main() {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clientConn.Listeners.AddListener(rec)
 | 
						clientConn.Listeners.AddListener(rec)
 | 
				
			||||||
	clientConn.Listeners.AddListener(&recorder.RfbRequester{Conn: clientConn, Name: "Rfb Requester"})
 | 
						clientConn.Listeners.AddListener(&recorder.RfbRequester{
 | 
				
			||||||
 | 
							Conn: clientConn,
 | 
				
			||||||
 | 
							Name: "Rfb Requester",
 | 
				
			||||||
 | 
							FullScreenRefreshInSec: 30, //create a full refresh key frame every 30sec for seeking
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	clientConn.Connect()
 | 
						clientConn.Connect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -189,6 +189,11 @@ func (r *Recorder) writeToDisk() error {
 | 
				
			|||||||
	paddedSize := (bytesLen + 3) & 0x7FFFFFFC
 | 
						paddedSize := (bytesLen + 3) & 0x7FFFFFFC
 | 
				
			||||||
	paddingSize := paddedSize - bytesLen
 | 
						paddingSize := paddedSize - bytesLen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// KeyFramePos, _ := r.writer.Seek(0, os.SEEK_CUR)
 | 
				
			||||||
 | 
						/// fi, err := r.writer.Stat()
 | 
				
			||||||
 | 
						/// KeyFramePos := fi.Size() + KeyFramePosInBuffer
 | 
				
			||||||
 | 
						// now save the KF pos in some file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//logger.Debugf("paddedSize=%d paddingSize=%d bytesLen=%d", paddedSize, paddingSize, bytesLen)
 | 
						//logger.Debugf("paddedSize=%d paddingSize=%d bytesLen=%d", paddedSize, paddingSize, bytesLen)
 | 
				
			||||||
	//write buffer padded to 32bit
 | 
						//write buffer padded to 32bit
 | 
				
			||||||
	_, err := r.buffer.WriteTo(r.writer)
 | 
						_, err := r.buffer.WriteTo(r.writer)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,11 +8,13 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RfbRequester struct {
 | 
					type RfbRequester struct {
 | 
				
			||||||
	Conn            *client.ClientConn
 | 
						Conn                   *client.ClientConn
 | 
				
			||||||
	Name            string
 | 
						Name                   string
 | 
				
			||||||
	Width           uint16
 | 
						Width                  uint16
 | 
				
			||||||
	Height          uint16
 | 
						Height                 uint16
 | 
				
			||||||
	lastRequestTime time.Time
 | 
						lastRequestTime        time.Time
 | 
				
			||||||
 | 
						nextFullScreenRefresh  time.Time
 | 
				
			||||||
 | 
						FullScreenRefreshInSec int // refresh interval (creates keyframes) if 0, disables keyframe creation
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *RfbRequester) Consume(seg *common.RfbSegment) error {
 | 
					func (p *RfbRequester) Consume(seg *common.RfbSegment) error {
 | 
				
			||||||
@@ -29,6 +31,7 @@ func (p *RfbRequester) Consume(seg *common.RfbSegment) error {
 | 
				
			|||||||
		p.Height = serverInitMessage.FBHeight
 | 
							p.Height = serverInitMessage.FBHeight
 | 
				
			||||||
		p.lastRequestTime = time.Now()
 | 
							p.lastRequestTime = time.Now()
 | 
				
			||||||
		p.Conn.FramebufferUpdateRequest(false, 0, 0, p.Width, p.Height)
 | 
							p.Conn.FramebufferUpdateRequest(false, 0, 0, p.Width, p.Height)
 | 
				
			||||||
 | 
							p.nextFullScreenRefresh = time.Now().Add(time.Duration(p.FullScreenRefreshInSec) * time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case common.SegmentMessageStart:
 | 
						case common.SegmentMessageStart:
 | 
				
			||||||
	case common.SegmentRectSeparator:
 | 
						case common.SegmentRectSeparator:
 | 
				
			||||||
@@ -39,7 +42,20 @@ func (p *RfbRequester) Consume(seg *common.RfbSegment) error {
 | 
				
			|||||||
		// timeForNextReq := p.lastRequestTime.Unix() + minTimeBetweenReq.Nanoseconds()/1000
 | 
							// timeForNextReq := p.lastRequestTime.Unix() + minTimeBetweenReq.Nanoseconds()/1000
 | 
				
			||||||
		// if seg.UpcomingObjectType == int(common.FramebufferUpdate) && time.Now().Unix() > timeForNextReq {
 | 
							// if seg.UpcomingObjectType == int(common.FramebufferUpdate) && time.Now().Unix() > timeForNextReq {
 | 
				
			||||||
		//time.Sleep(300 * time.Millisecond)
 | 
							//time.Sleep(300 * time.Millisecond)
 | 
				
			||||||
		p.Conn.FramebufferUpdateRequest(true, 0, 0, p.Width, p.Height)
 | 
							p.lastRequestTime = time.Now()
 | 
				
			||||||
 | 
							incremental := true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if p.FullScreenRefreshInSec > 0 {
 | 
				
			||||||
 | 
								// if p.nextFullScreenRefresh.IsZero() {
 | 
				
			||||||
 | 
								// 	p.nextFullScreenRefresh = time.Now().Add(time.Duration(p.FullScreenRefreshInSec) * time.Second)
 | 
				
			||||||
 | 
								// }
 | 
				
			||||||
 | 
								if time.Now().Sub(p.nextFullScreenRefresh) <= 0 {
 | 
				
			||||||
 | 
									logger.Warn(">>Creating keyframe")
 | 
				
			||||||
 | 
									p.nextFullScreenRefresh = time.Now().Add(time.Duration(p.FullScreenRefreshInSec) * time.Second)
 | 
				
			||||||
 | 
									incremental = false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							p.Conn.FramebufferUpdateRequest(incremental, 0, 0, p.Width, p.Height)
 | 
				
			||||||
		//}
 | 
							//}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user