熟悉远程桌面控制的朋友一定用过或听说过以下产品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 = document.getElementById("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 = myPics.getBoundingClientRect();
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: Math.round(boundRect.width),
height: Math.round(boundRect.height)
})
});
});
myPics.addEventListener("mouseup", function (e) {
x = e.offsetX;
y = e.offsetY;
b = e.button;
bmousedown=0
boundRect = myPics.getBoundingClientRect();
console.log("mouseup",bmousedown,e.offsetX, e.offsetY);
send({
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: Math.round(boundRect.width),
height: Math.round(boundRect.height)
})
});
});
myPics.addEventListener("mousedown", function (e) {
x = e.offsetX;
y = e.offsetY;
boundRect = myPics.getBoundingClientRect();
console.log("mousedown",e.offsetX, e.offsetY);
bmousedown=1
send({
type: "MOUSEDOWN",
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: Math.round(boundRect.width),
height: Math.round(boundRect.height)
})
});
});
myPics.addEventListener("DOMMouseScroll", function (e) {
console.log("wheel",event.wheelDelta || (-event.detail * 40));
boundRect = myPics.getBoundingClientRect();
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: Math.round(boundRect.width),
height: Math.round(boundRect.height),
wheel: event.wheelDelta || (-event.detail * 40)
})
});
if (e.preventDefault)
e.preventDefault();
if (e.stopPropagation)
e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
});
myPics.addEventListener("mousewheel", function (e) {
console.log("wheel",e.wheelDelta, e.detail);
boundRect = myPics.getBoundingClientRect();
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: Math.round(boundRect.width),
height: Math.round(boundRect.height),
wheel: e.wheelDelta ? e.wheelDelta : e.detail
})
});
if (e.preventDefault)
e.preventDefault();
if (e.stopPropagation)
e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
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) {
e.preventDefault();
return false;
});
}