Aa
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// agent-renderer.js — 브라우저 환경에서 실행됨 → WebRTC 사용 가능
|
||||
|
||||
let peerConnection = null;
|
||||
let socket = null;
|
||||
let currentStream = null;
|
||||
|
||||
// 메인 프로세스로부터 명령 수신 (IPC)
|
||||
@@ -9,19 +8,19 @@ console.log('electronAPI:', window.electronAPI);
|
||||
console.log('desktopCapturer:', window.desktopCapturer);
|
||||
|
||||
window.electronAPI.send('displays', { types: ['screen'] });
|
||||
window.electronAPI.receive('start-webrtc', async (payload) => {
|
||||
try {
|
||||
const { offer, displayId, signalingServer, targetId } = payload;
|
||||
console.log('start webrtc');
|
||||
// 1. Socket 연결 (렌더러에서도 가능)
|
||||
socket = io(signalingServer);
|
||||
socket.on('availableDisplays', async (sources) => {
|
||||
|
||||
const source = sources.find(s => {
|
||||
console.log(s.id, displayId)
|
||||
return s.id === displayId
|
||||
console.log('start webrtc');
|
||||
// 1. Socket 연결 (렌더러에서도 가능)
|
||||
|
||||
window.electronAPI.receive('start-webrtc', async (data) => {
|
||||
const source = data.sources.find(s => {
|
||||
return s.id === data.displayId
|
||||
});
|
||||
|
||||
// 3. WebRTC 연결
|
||||
peerConnection = new RTCPeerConnection({
|
||||
iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
|
||||
});
|
||||
if (!source) throw new Error('디스플레이 없음');
|
||||
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: false,
|
||||
@@ -35,59 +34,26 @@ window.electronAPI.receive('start-webrtc', async (payload) => {
|
||||
}
|
||||
});
|
||||
currentStream = stream;
|
||||
|
||||
|
||||
// 3. WebRTC 연결
|
||||
peerConnection = new RTCPeerConnection({
|
||||
iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
|
||||
});
|
||||
|
||||
stream.getTracks().forEach(track => {
|
||||
console.log('track', track, stream);
|
||||
peerConnection.addTrack(track, stream)
|
||||
});
|
||||
await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
|
||||
const answer = await peerConnection.createAnswer();
|
||||
await peerConnection.setLocalDescription(answer);
|
||||
|
||||
// 4. Answer 전송
|
||||
socket.emit('webrtcSignal', {
|
||||
targetId: targetId,
|
||||
type: 'answer',
|
||||
answer
|
||||
});
|
||||
|
||||
// 5. ICE candidate
|
||||
peerConnection.onicecandidate = (e) => {
|
||||
if (e.candidate) {
|
||||
socket.emit('webrtcSignal', {
|
||||
targetId: targetId,
|
||||
type: 'icecandidate',
|
||||
candidate: e.candidate
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 6. 입력 이벤트 수신 (robotjs는 메인 프로세스에서 실행 권장)
|
||||
socket.on('inputEvent', (data) => {
|
||||
window.electronApi.send('input-event-from-renderer', data);
|
||||
});
|
||||
|
||||
|
||||
console.log('✅ WebRTC 시작됨 (렌더러)');
|
||||
})
|
||||
|
||||
// 2. 화면 스트림 캡처
|
||||
socket.emit('requestDisplays', 'psn14020')
|
||||
|
||||
// const sources = await window.desktopCapturer.getSources({ types: ['screen'] });
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ WebRTC 실패:', err);
|
||||
window.electronApi.send('webrtc-error', err.message);
|
||||
}
|
||||
const offer = await peerConnection.createOffer({offerToReceiveVideo: true})
|
||||
await peerConnection.setLocalDescription(offer);
|
||||
window.electronAPI.send('offer', {type:'offer', targetId: data.targetId, offer})
|
||||
});
|
||||
|
||||
window.electronAPI.receive('displays', async (payload) => {
|
||||
window.desktopCapturer.getSources(['display'])
|
||||
});
|
||||
|
||||
|
||||
window.electronAPI.receive('answer', async (data) => {
|
||||
console.log('answer', data)
|
||||
await peerConnection.setRemoteDescription(new RTCSessionDescription(data.answer));
|
||||
console.log('connect')
|
||||
})
|
||||
|
||||
window.electronAPI.receive('webrtcSignal', async (data) => {
|
||||
try {
|
||||
|
||||
33
main.js
33
main.js
@@ -16,6 +16,7 @@ let socket = null;
|
||||
let peerConnection = null;
|
||||
let displayId = null;
|
||||
let offer = null;
|
||||
let sources = null;
|
||||
|
||||
// 자동 시작 설정
|
||||
app.setLoginItemSettings({
|
||||
@@ -54,10 +55,9 @@ function createTray() {
|
||||
// 🖥️ 사용 가능한 디스플레이 목록 전송
|
||||
async function sendAvailableDisplays() {
|
||||
try {
|
||||
const sources = await desktopCapturer.getSources({ types: ['screen'] });
|
||||
sources = await desktopCapturer.getSources({ types: ['screen'] });
|
||||
const source = sources[0];
|
||||
displayId = source.id
|
||||
console.log('sources',sources)
|
||||
const displays = sources.map(source => ({
|
||||
id: source.id,
|
||||
name: source.name,
|
||||
@@ -104,17 +104,22 @@ function connectToSignaling() {
|
||||
reconnectionDelay: 2000
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
socket.on('connect', (data) => {
|
||||
console.log('시그널링 서버 연결됨. 직원 등록 중...');
|
||||
socket.emit('register', EMPLOYEE_ID);
|
||||
sendAvailableDisplays(); // 연결 시 디스플레이 목록 전송
|
||||
|
||||
// rendererWindow.webContents.send('connection', data);
|
||||
});
|
||||
|
||||
socket.on('controlRequest', async (data) => {
|
||||
|
||||
/*연결 요청 -> webrtc 시작 -> offer 전송*/
|
||||
socket.on('responseControl', async (data) => {
|
||||
console.log(data)
|
||||
const result = await dialog.showMessageBox({
|
||||
type: 'question',
|
||||
title: '원격 연결 요청',
|
||||
message: `관리자로부터 원격 제어 요청이 왔습니다.\n허용하시겠습니까? ${displayId}`,
|
||||
message: `관리자로부터 원격 제어 요청이 왔습니다.\n허용하시겠습니까? ${data.displayId}`,
|
||||
buttons: ['허용', '거부'],
|
||||
defaultId: 1,
|
||||
cancelId: 1
|
||||
@@ -123,16 +128,20 @@ function connectToSignaling() {
|
||||
if (result.response === 0) {
|
||||
// ✅ 렌더러 프로세스에 WebRTC 시작 명령 전달
|
||||
rendererWindow.webContents.send('start-webrtc', {
|
||||
offer: data.offer,
|
||||
displayId,
|
||||
signalingServer: SIGNALING_SERVER,
|
||||
targetId: data.from
|
||||
displayId: data.displayId,
|
||||
targetId: data.targetId,
|
||||
sources
|
||||
});
|
||||
} else {
|
||||
socket.emit('webrtcSignal', { targetId: data.from, data: { type: 'reject' } });
|
||||
socket.emit('webrtcSignal', { targetId: data.targetId, data: { type: 'reject' } });
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('answer', async (data) => {
|
||||
rendererWindow.webContents.send('answer', data);
|
||||
console.log('answer', data);
|
||||
})
|
||||
|
||||
// WebRTC 신호 수신 (ICE candidate 등)
|
||||
socket.on('webrtcSignal', async (data) => {
|
||||
rendererWindow.webContents.send('webrtcSignal', data);
|
||||
@@ -186,3 +195,7 @@ ipcMain.on('input-event-from-renderer', (event, data) => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('offer', (event, data) => {
|
||||
socket.emit('offer', data);
|
||||
})
|
||||
Reference in New Issue
Block a user