asdf
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
let peerConnection = null;
|
let peerConnection = null;
|
||||||
let currentStream = null;
|
let currentStream = null;
|
||||||
|
let dataChannel = null;
|
||||||
let connection = false;
|
let connection = false;
|
||||||
// 메인 프로세스로부터 명령 수신 (IPC)
|
// 메인 프로세스로부터 명령 수신 (IPC)
|
||||||
console.log('electronAPI:', window.electronAPI);
|
console.log('electronAPI:', window.electronAPI);
|
||||||
@@ -53,6 +54,16 @@ window.electronAPI.receive('start-webrtc', async (data) => {
|
|||||||
window.electronAPI.send('icecandidate', {type: 'icecandidate', targetId: data.targetId, server:'agent', 'candidate': event.candidate});
|
window.electronAPI.send('icecandidate', {type: 'icecandidate', targetId: data.targetId, server:'agent', 'candidate': event.candidate});
|
||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peerConnection.ondatachannel = (event) => {
|
||||||
|
console.log('datachannel', event);
|
||||||
|
dataChannel = event.channel;
|
||||||
|
dataChannel.onmessage = (event) => {
|
||||||
|
window.electronAPI.send('inputEvent', JSON.parse(event.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
window.electronAPI.receive('displays', async (data) => {
|
window.electronAPI.receive('displays', async (data) => {
|
||||||
@@ -66,5 +77,10 @@ window.electronAPI.receive('icecandidate', async (data) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.electronAPI.receive('disconnect', async (data) => {
|
||||||
|
peerConnection.close();
|
||||||
|
peerConnection = null;
|
||||||
|
});
|
||||||
|
|
||||||
// desktopCapturer 사용을 위해 preload 필요
|
// desktopCapturer 사용을 위해 preload 필요
|
||||||
// → 다음 단계에서 preload.js 설정
|
// → 다음 단계에서 preload.js 설정
|
||||||
85
main.js
85
main.js
@@ -3,17 +3,16 @@ const { app, BrowserWindow, Tray, Menu, nativeImage, dialog, ipcMain } = require
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const io = require('socket.io-client');
|
const io = require('socket.io-client');
|
||||||
const { desktopCapturer } = require('electron');
|
const { desktopCapturer } = require('electron');
|
||||||
const { mouse, Point, straightTo, keyboard, Key, clipboard } = require('@nut-tree-fork/nut-js')
|
const { mouse, Point, straightTo, keyboard, Key, clipboard, Button} = require('@nut-tree-fork/nut-js')
|
||||||
// 고유 직원 ID
|
// 고유 직원 ID
|
||||||
const EMPLOYEE_ID = "psn14020";
|
const EMPLOYEE_ID = "psn14020";
|
||||||
|
|
||||||
// 시그널링 서버 주소
|
// 시그널링 서버 주소
|
||||||
const SIGNALING_SERVER = 'http://localhost:3001';
|
const SIGNALING_SERVER = 'http://192.168.0.148:3001';
|
||||||
|
|
||||||
let tray = null;
|
let tray = null;
|
||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
let socket = null;
|
let socket = null;
|
||||||
let peerConnection = null;
|
|
||||||
let displayId = null;
|
let displayId = null;
|
||||||
let offer = null;
|
let offer = null;
|
||||||
let sources = null;
|
let sources = null;
|
||||||
@@ -69,31 +68,44 @@ async function sendAvailableDisplays() {
|
|||||||
console.error('디스플레이 목록 가져오기 실패:', err);
|
console.error('디스플레이 목록 가져오기 실패:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const keyMap = {
|
||||||
|
Enter: Key.Enter,
|
||||||
|
Backspace: Key.Backspace,
|
||||||
|
Tab: Key.Tab,
|
||||||
|
Escape: Key.Escape,
|
||||||
|
ArrowDown: Key.Down,
|
||||||
|
ArrowUp: Key.Up,
|
||||||
|
ArrowLeft: Key.Left,
|
||||||
|
ArrowRight: Key.Right,
|
||||||
|
}
|
||||||
// 🖱️ 입력 이벤트 처리 (robotjs 필요)
|
// 🖱️ 입력 이벤트 처리 (robotjs 필요)
|
||||||
function setupInputHandler() {
|
async function setupInputHandler(data) {
|
||||||
// robotjs는 별도 설치 및 권한 필요
|
// robotjs는 별도 설치 및 권한 필요
|
||||||
|
|
||||||
socket.on('inputEvent', async({ type, ...data }) => {
|
if (data.type === 'mouse') {
|
||||||
try {
|
const { x, y, action } = data;
|
||||||
if (type === 'mouse') {
|
if(x === null || y === null) return
|
||||||
const { x, y, action } = data;
|
const targetPoint = new Point(x, y)
|
||||||
const targetPoint = new Point(x, y)
|
await mouse.move(straightTo(targetPoint));
|
||||||
await mouse.move(straightTo(targetPoint));
|
console.log(x, y , action)
|
||||||
if (action === 'click') {
|
if (action === 'click') {
|
||||||
await mouse.leftClick();
|
await mouse.click(Button.LEFT)
|
||||||
}
|
|
||||||
} else if (type === 'keyboard') {
|
|
||||||
const { key } = data;
|
|
||||||
// 간단한 키 매핑 (보안상 복잡한 키는 제한 권장)
|
|
||||||
if (key.length === 1 || ['Enter', 'Backspace', 'Tab', 'Escape'].includes(key)) {
|
|
||||||
await keyboard.pressKey(key.toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('입력 이벤트 처리 오류:', err);
|
|
||||||
}
|
}
|
||||||
});
|
} else if (data.type === 'keyboard') {
|
||||||
|
const { key } = data;
|
||||||
|
// 간단한 키 매핑 (보안상 복잡한 키는 제한 권장)
|
||||||
|
console.log(key)
|
||||||
|
if(['Enter', 'Backspace', 'Tab', 'Escape'
|
||||||
|
, 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(key)) {
|
||||||
|
await keyboard.pressKey(keyMap[key]);
|
||||||
|
await keyboard.releaseKey(keyMap[key]);
|
||||||
|
} else if(key.length === 1) {
|
||||||
|
await keyboard.type(key.toLowerCase());
|
||||||
|
}
|
||||||
|
// if (key.length === 1 || ['Enter', 'Backspace', 'Tab', 'Escape'].includes(key)) {
|
||||||
|
// await keyboard.type(key.toLowerCase());
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 시그널링 연결
|
// 시그널링 연결
|
||||||
@@ -120,10 +132,7 @@ function connectToSignaling() {
|
|||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
console.log('시그널링 서버와 연결 끊김');
|
console.log('시그널링 서버와 연결 끊김');
|
||||||
if (peerConnection) {
|
rendererWindow.webContents.send('disconnect');
|
||||||
peerConnection.close();
|
|
||||||
peerConnection = null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('responseOffer', async (data) => {
|
socket.on('responseOffer', async (data) => {
|
||||||
@@ -175,22 +184,6 @@ app.on('window-all-closed', () => {
|
|||||||
// Windows/Linux에서 종료하지 않음
|
// Windows/Linux에서 종료하지 않음
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('input-event-from-renderer', (event, data) => {
|
|
||||||
// 여기서 robotjs로 입력 실행 (메인 프로세스에서만 가능)
|
|
||||||
try {
|
|
||||||
const robot = require('robotjs');
|
|
||||||
if (data.type === 'mouse') {
|
|
||||||
robot.moveMouse(Math.round(data.x), Math.round(data.y));
|
|
||||||
if (data.action === 'click') robot.mouseClick();
|
|
||||||
} else if (data.type === 'keyboard') {
|
|
||||||
robot.keyTap(data.key);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('robotjs 오류:', e);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
ipcMain.on('requestAnswer', (event, data) => {
|
ipcMain.on('requestAnswer', (event, data) => {
|
||||||
socket.emit('requestAnswer', data);
|
socket.emit('requestAnswer', data);
|
||||||
})
|
})
|
||||||
@@ -204,3 +197,7 @@ ipcMain.on('start', (event, data) => {
|
|||||||
console.log('start', data);
|
console.log('start', data);
|
||||||
socket.emit('start', data);
|
socket.emit('start', data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.on('inputEvent', (event, data) => {
|
||||||
|
setupInputHandler(data)
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user