基于webrtc技术的远程桌⾯控制系统(⼀)
熟悉远程桌⾯控制的朋友⼀定⽤过或听说过以下产品pc anywhere 、teamview、向⽇葵、rustdesk等等,远程技术⽇新⽉异,协议也百花齐放,RDP VNC SSH TELNET都⼤放异彩。
随着⽹络带宽的⼤⼤提升,远程控制的互动交互进⼊⼀个新的阶段,我准备抽时间将远程控制所需的核⼼技术逐⼀展⽰,并以此实现⼀款强⼤的远程办公硬件。
⾸先,浏览器已经不可替代,为了不安装软件,我们选择采⽤浏览器作为本地桌⾯的载体,⿏标键盘⼜是图形交互不可或缺的外设,所以我选择第⼀课采⽤js实现本地⿏标键盘的采集和传输。这是基本技能,也是⼤杀器,不废话,直接上核⼼代码代码,以下代码实现了监听⿏标的移动坐标事件、左右按钮以及滚轮事件,键盘键值等,并通过webrtc 的datachannel传输⾄远端被控设备,实现键盘⿏标的同步:
function KeyMouseCtrl()
{
initControlHID()
var keyboardenable=true
var mouseenable=true
var bmousedown=0
if (keyboardenable){
document.addEventListener("keydown", function (event) {
logKey(event);
return false;
});
}
document.addEventListener("mousewheel", function (event) {
console.log("mouse wheel",event.wheelDelta ? event.wheelDelta : event.detail) ;
return false;
});
document.addEventListener("contextmenu", function (event) {
return event.preventDefault();
});
document.addEventListener("DOMMouseScroll", function (event) {
console.log("mouse wheel",-event.wheelDelta*40 ? event.wheelDelta : event.detail,event.wheelDelta || (-event.detail * 40)) ;
return false;
var myPics = ElementById("remote-video"); // Add the event listeners for //mousedown, mousemove, and mouseup
if (mouseenable) {
myPics.addEventListener("mousemove", function (e) {
x = e.offsetX;
y = e.offsetY;
b = e.button;
boundRect = BoundingClientRect();
console.log("mouse move",bmousedown,e.offsetX, e.offsetY);
send({
type: "MOUSEMOVE",
data: JSON.stringify({
isLeft: e.button == 0 ? 1 : 0,
isMiddle: e.button == 1 ? 1 : 0,
isRight: e.button == 2 ? 1 : 0,
isDown: bmousedown,
x: e.offsetX,
y: e.offsetY,
width: und(boundRect.width),
height: und(boundRect.height)
})
});
});
myPics.addEventListener("mouseup", function (e) {
x = e.offsetX;
y = e.offsetY;
b = e.button;
bmousedown=0
boundRect = BoundingClientRect();
console.log("mouseup",bmousedown,e.offsetX, e.offsetY);
type: "MOUSEUP",
data: JSON.stringify({
isLeft: e.button == 0 ? 1 : 0,
isMiddle: e.button == 1 ? 1 : 0,
isRight: e.button == 2 ? 1 : 0,
isDown: bmousedown,
x: e.offsetX,
y: e.offsetY,
width: und(boundRect.width),
height: und(boundRect.height)
})
});
});
myPics.addEventListener("mousedown", function (e) { x = e.offsetX;
y = e.offsetY;
boundRect = BoundingClientRect(); console.log("mousedown",e.offsetX, e.offsetY); bmousedown=1
send({
type: "MOUSEDOWN",
data: JSON.stringify({
webrtc浏览器isLeft: e.button == 0 ? 1 : 0,
isMiddle: e.button == 1 ? 1 : 0,
isRight: e.button == 2 ? 1 : 0,
isDown: 1,
x: e.offsetX,
y: e.offsetY,
width: und(boundRect.width),
height: und(boundRect.height)
})
});
});
});
myPics.addEventListener("DOMMouseScroll", function (e) { console.log("wheel",event.wheelDelta || (-event.detail * 40)); boundRect = BoundingClientRect();
console.log(e.offsetX, e.offsetY);
send({
type: "MOUSEWHEEL",
data: JSON.stringify({
isLeft: e.button == 0 ? 1 : 0,
isMiddle: e.button == 1 ? 1 : 0,
isRight: e.button == 2 ? 1 : 0,
isDown: 1,
x: e.offsetX,
y: e.offsetY,
width: und(boundRect.width),
height: und(boundRect.height),
wheel: event.wheelDelta || (-event.detail * 40)
})
});
if (e.preventDefault)
e.preventDefault();
if (e.stopPropagation)
e.stopPropagation();
e.cancelBubble = true;
return false;
});
myPics.addEventListener("mousewheel", function (e) { console.log("wheel",e.wheelDelta, e.detail);
boundRect = BoundingClientRect();
console.log(e.offsetX, e.offsetY);
send({
type: "MOUSEWHEEL",
data: JSON.stringify({
isLeft: e.button == 0 ? 1 : 0,
isMiddle: e.button == 1 ? 1 : 0,
isRight: e.button == 2 ? 1 : 0,
isDown: 1,
x: e.offsetX,
y: e.offsetY,
width: und(boundRect.width),
height: und(boundRect.height),
wheel: e.wheelDelta ? e.wheelDelta : e.detail })
});
if (e.preventDefault)
e.preventDefault();
if (e.stopPropagation)
e.stopPropagation();
e.cancelBubble = true;
return false;
});
myPics.addEventListener("keydown", function (e) { e.preventDefault();
return false;
});
myPics.addEventListener("keyup", function (e) { e.preventDefault();
return false;
});
}
myPics.addEventListener("click", function (e) {