亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

Node.js 實現遠程桌面監控的方法步驟

2024-05-06 16:52:59
字體:
來源:轉載
供稿:網友

描述

最近使用node實現了一個遠程桌面監控的應用,分為服務端和客戶端,客戶端可以實時監控服務端的桌面,并且可以通過鼠標和鍵盤來控制服務端的桌面。

Node.js,遠程桌面監控

Node.js,遠程桌面監控

這里因為我是用的同一臺電腦,所以監控畫面是這樣的,當然使用兩臺電腦一個跑客戶端,一個跑服務端才有意義。

原理

其實這個應用的功能主要分為兩部分,一是實現監控,即在客戶端可以看到服務端的桌面,這部分功能是通過定時截圖來實現的,比如服務端一秒截幾次圖,然后通過socketio發送到客戶端,客戶端通過改變img的src來實現一幀幀的顯示最新的圖片,這樣就能看到動態的桌面了。監控就是這樣實現的。

另一個功能是控制,即客戶端對監控畫面的操作,包括鼠標和鍵盤的操作都可以在服務端的桌面真正的生效,這部分功能的實現是在electron的應用中監聽了所有的鼠標和鍵盤事件,比如keydown、keyup、keypress,mousedown、mouseup、mousemove、click等,然后通過socketio把事件傳遞到服務端,服務端通過 robot-js來執行不同的事件,這樣就能使得客戶端的事件在服務端觸發了。

實現

原理講完,我們來具體實現一下(源碼鏈接在這)。

實現socket通信

首先,服務端和客戶端分別引入socket.io和socket.io-client, 分別初始化

服務端:

const app = new Koa();const server = http.createServer(app.callback());createSocketIO(server);app.use((ctx): void => {  ctx.body = 'please connect use socket';});server.listen(port, (): void => {  console.log('server started at http://localhost:' + port);});//createSocketIOconst io = socketIO(server, {    pingInterval: 10000,    pingTimeout: 5000,    cookie: false  });io.on('connect', (socket): void => {  socket.emit('msg', 'connected');}

客戶端:

var socket = this.socket = io('http://' + this.ip + ':3000')socket.on('msg', (msg) => { console.log(msg)})socket.on('error', (err) => { alert('出錯了' + err)})

這樣,服務端和客戶端就通過socketio建立了鏈接。

實現桌面監控

之后我們首先要在服務端來截圖,使用screenshot-desktop這個包

const screenshot = require('screenshot-desktop')const SCREENSHOT_INTERVAL = 500;export const createScreenshot = (): Promise<[string, Buffer]> => {  return screenshot({format: 'png'}).then((img): [string, Buffer] => {    return [ img.toString('base64'), img];  }).catch((err): {} => {    console.log('截圖失敗', err);    return err;  })}export const startScreenshotTimer = (callback): {} => {  return setInterval((): void => {    createScreenshot().then(([imgStr, img]): void => {      callback(['data:image/png;base64,' + imgStr, img]);    })  }, SCREENSHOT_INTERVAL)}

然后通過socketio的emit來傳到客戶端:

startScreenshotTimer(([imgStr, img]): void => {  io.sockets.emit('screenshot', imgStr);});

客戶端收到圖片后,設置到img的src上(這里是base64的圖片url):

 <img   class="screenshot"   :src="screenshot"/>
data () { return {  screenshot: '' }}
socket.on('screenshot', (data) => { this.screenshot = data})

其實這樣就已經實現了桌面監控了,有興趣的同學可以照著這個思路實現看看,并不是很麻煩。

當然這樣的方案是有問題的,因為我們需要知道服務端桌面尺寸的大小,然后根據這個來調整客戶端顯示的圖片尺寸。

實現這個細節是使用的get-pixels這個庫,可以讀取本地圖片文件的寬度高度等信息,所以我先把圖片寫入本地,然后又讀取出來,這樣獲取到的屏幕尺寸。

interface ScreenSize {  width: number;  height: number;}function getScreenSize(img): Promise<ScreenSize> {  const imgPath = path.resolve(process.cwd(), './tmp.png');  fs.writeFileSync(imgPath, img);  return new Promise((resolve): void => {    getPixels(imgPath, function(err, pixels): void {      if(err) {        console.log("Bad image path")        return      }      resolve({        width: pixels.shape[0],        height: pixels.shape[1]      });    });  })}

然后通過socektio傳遞給客戶端

getScreenSize(img).then(({ width, height}) => {  io.sockets.emit('screensize', {    width,    height  })});

客戶端收到之后調整圖片大小就可以了

<img   class="screenshot"   :src="screenshot"  :style="screenshotStyle"/>
data () { return {  screenshot: '',  screenshotStyle: '', }}
socket.on('screensize', (screensize) => { this.screenshotStyle = {'width': screensize.width + 'px', 'height': screensize.height + 'px'}})

至此已經實現了桌面監控,并且圖片尺寸和服務端屏幕的尺寸是一致的。

這里還有一個細節,就是獲取到的圖片大小是物理像素,而客戶端設置的px是設備無關像素,也就是要除以dpr才是px的值。這里需要獲取dpr,因為目前只是在mac下用,所以直接除以2了。

實現遠程控制

代碼寫到這里,客戶端的electron應用中已經可以實時顯示服務端的桌面了。(當然像輸入ip的彈框,以及electron-vue和typescript等和主要邏輯無關的細節就不展開了。)

接下來我們要實現遠程控制,也就是監聽事件,傳遞事件,執行事件這幾部分。

首先我們定義一下傳遞的事件的格式:

interface MouseEvent {  type: string;  buttonType: string;  x: number;  y: number;}interface KeyboardEvent {  type: string;  keyCode: number;  keyName: string;}

鼠標事件MouseEvent,type為鼠標事件的類型,具體的值包括mousedown、mouseup、mousemove、click、dblclick,buttonType指的是鼠標的左鍵還是右鍵,值為 left 或 right,x和y是具體的坐標。

鍵盤事件KeyboardEvent,type為鍵盤事件的類型,具體的值包括keydown、keyup、keypress,keyCode為鍵盤碼,keyName為鍵的名字。

接下來我們要在客戶端監聽事件:

<img   class="screenshot"   :src="screenshot"  :style="screenshotStyle"  @mousedown="handleMouseEvent"  @mousemove="handleMouseEvent"   @mouseup="handleMouseEvent"  @click="handleMouseEvent"  @dblclick="handleMouseEvent"  />
window.onkeypress = window.onkeyup = window.onkeydown = this.handleKeyboardEvent

通過socekt把事件傳遞到服務端

 handleKeyboardEvent (e) {  this.socket && this.socket.emit('userevent', {   type: 'keyboard',   event: {    type: e.type,    keyName: e.key,    keyCode: e.keyCode   }  }) }, handleMouseEvent (e) {  this.socket && this.socket.emit('userevent', {   type: 'mouse',   event: {    type: e.type,    buttonType: e.buttons === 2 ? 'right' : 'left',    x: e.clientX,    y: e.clientY   }  }) },

然后在服務端把事件取出來執行,執行事件使用的是robot-js:

const { Mouse, Point, Keyboard } = require('robot-js');interface MouseEvent {  type: string;  buttonType: string;  x: number;  y: number;}interface KeyboardEvent {  type: string;  keyCode: number;  keyName: string;}export default class EventExecuter {  public mouse;  public keyboard;  public constructor(){    this.mouse = new Mouse();    this.keyboard = new Keyboard();  }  public executeKeyboardEvent(event: KeyboardEvent): void {    switch(event.type) {      case 'keydown':        this.keyboard.press(event.keyCode);        break;      case 'keyup':        this.keyboard.release(event.keyCode);        break;      case 'keypress':        this.keyboard.click(event.keyCode);        break;      default: break;    }  }  public executeMouseEvent(event): void {    Mouse.setPos(new Point(event.x, event.y));    const button = event.buttonType === 'left' ? 0 : 2    switch(event.type) {      case 'mousedown':        this.mouse.press(button);        break;      case 'mousemove':        break;      case 'mouseup':         this.mouse.release(button);        break;      case 'click':         this.mouse.click(button);        break;      case 'dblclick':         this.mouse.click(button);        this.mouse.click(button);        break;      default: break;    }  }  public exectue(eventInfo): void {    console.log(eventInfo);    switch (eventInfo.type) {      case 'keyboard':        this.executeKeyboardEvent(eventInfo.event);        break;      case 'mouse':        this.executeMouseEvent(eventInfo.event);        break;      default: break;    }  }}

至此,桌面監控和遠程控制的客戶端還有服務端的部分,以及兩端的通信都已經實現了。思路其實并不麻煩,但細節還是很多的。有興趣的同學可以把代碼下下來跑跑試試,或者按著這個思路自己實現一遍,還是挺好玩的。

源碼鏈接

remote-monitor-server

remote-monitor-client

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久综合网天天| 久久久久久久激情视频| 国产精品女人久久久久久| 亚洲在线第一页| 国产精品揄拍一区二区| 性色av一区二区三区| 亚洲精品福利资源站| 欧美插天视频在线播放| 久久精品99国产精品酒店日本| 亚洲天堂av图片| 国产69久久精品成人| 亚洲va欧美va在线观看| 亚洲人午夜精品免费| 亚洲欧美国产一本综合首页| 精品亚洲va在线va天堂资源站| 欧美激情视频在线观看| 成人黄色午夜影院| 国产一区二中文字幕在线看| 欧美日韩国产成人在线| 国产亚洲激情在线| 91中文字幕一区| 国产一区二区三区在线观看视频| 国内精品一区二区三区四区| 91欧美精品成人综合在线观看| 中文字幕一精品亚洲无线一区| 亚洲成人激情视频| 日韩中文字幕在线免费观看| 美女少妇精品视频| 亚洲国产日韩一区| 国产精品久久国产精品99gif| 欧美性69xxxx肥| 日韩欧美国产视频| 日本亚洲欧洲色| 国产成人精品在线| 欧美性jizz18性欧美| 国产精品视频区1| 日韩久久精品成人| 欧美夫妻性生活xx| 欧美三级xxx| 日韩欧美在线第一页| 国产成人+综合亚洲+天堂| 91在线国产电影| 国产欧美精品一区二区| 国产福利成人在线| 91在线观看欧美日韩| 亚洲91精品在线| 国产一区私人高清影院| 久久久精品视频在线观看| 国产综合色香蕉精品| 九九九久久久久久| 日韩影视在线观看| 久久国产一区二区三区| 国产成人精品视| 欧美一级淫片videoshd| 国产一区二中文字幕在线看| 久久亚洲精品毛片| 国产成人亚洲精品| 亚洲精品v天堂中文字幕| 日韩美女免费线视频| 国产精品av免费在线观看| 欧美日韩亚洲一区二区| 精品久久久久人成| 精品久久久久久久中文字幕| 91av中文字幕| 国产成人精品久久二区二区| 少妇激情综合网| 欧美成人性色生活仑片| 国内精品视频一区| 91精品国产777在线观看| 亚洲欧美激情视频| 亚洲美女性视频| 国产97在线|日韩| 国产精品视频自在线| 亚洲成人网av| 九九热精品视频国产| 欧美激情久久久久| 欧洲精品在线视频| 国模gogo一区二区大胆私拍| 色一情一乱一区二区| 欧美麻豆久久久久久中文| 欧美激情在线观看视频| 欧美一级高清免费播放| 91欧美精品成人综合在线观看| 亚洲欧美日韩精品久久奇米色影视| 亚洲男女自偷自拍图片另类| 97久久精品视频| 国产999视频| 97精品伊人久久久大香线蕉| 亚洲乱亚洲乱妇无码| 96精品久久久久中文字幕| 91经典在线视频| 亚洲国语精品自产拍在线观看| 主播福利视频一区| 97视频免费看| 亚洲精品电影在线观看| 亚洲欧美日韩中文在线制服| xvideos国产精品| 亚洲国产一区二区三区四区| 在线成人激情视频| 欧美裸体xxxx极品少妇软件| 亚洲国产成人久久综合一区| 国产偷国产偷亚洲清高网站| 国产午夜精品久久久| 91精品啪在线观看麻豆免费| 亚洲成人黄色在线| 久久久亚洲福利精品午夜| 亚洲精品福利在线观看| 欧美在线亚洲一区| 精品视频偷偷看在线观看| 欧美国产日韩一区| 日本国产一区二区三区| 欧美午夜精品伦理| 日韩欧美在线国产| 青青a在线精品免费观看| 久久精品免费电影| 成人精品一区二区三区| 91高潮在线观看| 精品久久久久久国产| 国产欧美精品一区二区三区-老狼| 福利一区视频在线观看| 欧美成人在线免费| 26uuu国产精品视频| 欧洲s码亚洲m码精品一区| 91天堂在线视频| 欧美成人精品三级在线观看| 久久夜色精品国产欧美乱| 成人激情在线播放| 欧美日韩免费网站| 国产欧美日韩精品丝袜高跟鞋| 久久6免费高清热精品| 日韩视频精品在线| 中文字幕亚洲欧美日韩高清| 久久色免费在线视频| 日韩专区在线播放| 成人久久一区二区三区| 中文字幕在线亚洲| 成人黄色av网| 欧美肥臀大乳一区二区免费视频| 国产精品国产自产拍高清av水多| 亚洲福利视频网| 性色av一区二区三区免费| 亚洲第一中文字幕在线观看| 欧美日韩国产综合视频在线观看中文| 富二代精品短视频| 成人精品aaaa网站| 日韩在线视频免费观看| 国产伦精品免费视频| 亚洲国产精品电影| 欧美精品免费在线| 欧美理论片在线观看| 久久精品国产电影| 久青草国产97香蕉在线视频| 欧美日韩成人在线播放| 九九九久久国产免费| 亚洲iv一区二区三区| 国产精品福利观看| 在线免费观看羞羞视频一区二区| 日本午夜人人精品| 久久久久久噜噜噜久久久精品| 精品视频9999| 久久理论片午夜琪琪电影网| 日本三级韩国三级久久| 亚洲精美色品网站| 亚洲欧洲视频在线|