This commit is contained in:
wow22831 2024-10-28 01:34:24 +07:00
parent 8a9b66b1fd
commit 8c7b33c853
2 changed files with 82 additions and 18 deletions

View File

@ -6,6 +6,8 @@ import {
} from '@ionic/react';
import { call as callIcon, close as hangUpIcon } from 'ionicons/icons';
const socket = new WebSocket('ws://192.168.0.160:8080'); // Адрес вашего WebSocket сервера
const ExploreContainer: React.FC = () => {
const [callString, setCallString] = useState(""); // Здесь будет храниться IP-адрес получателя звонка
const [isEnable, setIsEnable] = useState(true);
@ -17,12 +19,11 @@ const ExploreContainer: React.FC = () => {
const [peerConnection, setPeerConnection] = useState<RTCPeerConnection | null>(null);
const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);
// Создаем RTCPeerConnection без использования ICE-серверов
// Инициализация WebRTC соединения
useEffect(() => {
const pc = new RTCPeerConnection();
setPeerConnection(pc);
// Получаем удаленные медиа-потоки
pc.ontrack = (event) => {
const [stream] = event.streams;
setRemoteStream(stream);
@ -31,17 +32,41 @@ const ExploreContainer: React.FC = () => {
pc.onicecandidate = (event) => {
if (event.candidate) {
console.log('ICE Candidate:', event.candidate);
// В локальной сети с фиксированными IP это обычно не требуется, но можно отправить кандидата вручную
socket.send(JSON.stringify({
type: 'ice-candidate',
candidate: event.candidate,
target: callString,
}));
}
};
return () => {
pc.close();
};
}, []);
}, [callString]);
// Запуск вызова (инициатор соединения)
// Обработка входящих сообщений WebSocket
useEffect(() => {
socket.onmessage = async (event) => {
const data = JSON.parse(event.data);
if (data.type === 'offer') {
await handleIncomingCall(data.offer);
} else if (data.type === 'answer') {
if (peerConnection) {
await peerConnection.setRemoteDescription(new RTCSessionDescription(data.answer));
}
} else if (data.type === 'ice-candidate' && peerConnection) {
try {
await peerConnection.addIceCandidate(new RTCIceCandidate(data.candidate));
} catch (error) {
console.error('Ошибка добавления ICE-кандидата', error);
}
}
};
}, [peerConnection]);
// Запуск вызова
const makeCall = useCallback(async () => {
if (peerConnection && callString) {
setIsLoading(true);
@ -49,16 +74,16 @@ const ExploreContainer: React.FC = () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
setLocalStream(stream);
// Добавляем треки к соединению
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
// Создаем SDP предложение для вызова
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// Отправляем SDP предложение получателю (на callString, можно использовать HTTP запрос)
console.log('SDP Offer:', offer);
// Здесь можно использовать WebSocket или другой способ обмена SDP в локальной сети
socket.send(JSON.stringify({
type: 'offer',
offer: offer,
target: callString,
}));
setIsLoading(false);
setIsCallActive(true);
@ -72,7 +97,7 @@ const ExploreContainer: React.FC = () => {
}
}, [peerConnection, callString]);
// Принятие входящего звонка (ответ)
// Принятие входящего звонка
const handleIncomingCall = useCallback(async (offer: RTCSessionDescriptionInit) => {
if (peerConnection) {
try {
@ -80,16 +105,16 @@ const ExploreContainer: React.FC = () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
setLocalStream(stream);
// Добавляем треки к соединению
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
// Создаем SDP ответ
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
// Отправляем SDP ответ инициатору
console.log('SDP Answer:', answer);
// Также отправляем SDP ответ инициатору через HTTP/WebSocket
socket.send(JSON.stringify({
type: 'answer',
answer: answer,
target: callString,
}));
setIsCallActive(true);
startCallTimer();
@ -97,7 +122,7 @@ const ExploreContainer: React.FC = () => {
console.error('Ошибка обработки входящего вызова', err);
}
}
}, [peerConnection]);
}, [peerConnection, callString]);
// Завершение звонка
const endCall = useCallback(() => {

View File

@ -0,0 +1,39 @@
// Установите Node.js и ws с помощью команды: npm install ws
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
const clients = {};
server.on('connection', (socket) => {
socket.on('message', (message) => {
const data = JSON.parse(message);
switch (data.type) {
case 'register':
clients[data.name] = socket;
console.log(`Клиент ${data.name} подключен`);
break;
case 'offer':
case 'answer':
case 'ice-candidate':
const targetSocket = clients[data.target];
if (targetSocket) {
targetSocket.send(JSON.stringify(data));
} else {
console.log(`Целевой клиент ${data.target} не найден`);
}
break;
}
});
socket.on('close', () => {
for (let name in clients) {
if (clients[name] === socket) {
console.log(`Клиент ${name} отключен`);
delete clients[name];
break;
}
}
});
});
console.log('WebSocket сервер запущен на ws://192.168.0.160:8080');