132 lines
3.6 KiB
TypeScript
132 lines
3.6 KiB
TypeScript
const servers = {
|
|
iceServers: [
|
|
{ url: 'stun:stun01.sipphone.com' },
|
|
{ url: 'stun:stun.ekiga.net' },
|
|
{ url: 'stun:stun.fwdnet.net' },
|
|
{ url: 'stun:stun.ideasip.com' },
|
|
{ url: 'stun:stun.iptel.org' },
|
|
{ url: 'stun:stun.rixtelecom.se' },
|
|
{ url: 'stun:stun.schlund.de' },
|
|
{ url: 'stun:stun.l.google.com:19302' },
|
|
{ url: 'stun:stun1.l.google.com:19302' },
|
|
{ url: 'stun:stun2.l.google.com:19302' },
|
|
{ url: 'stun:stun3.l.google.com:19302' },
|
|
{ url: 'stun:stun4.l.google.com:19302' },
|
|
{ url: 'stun:stunserver.org' },
|
|
{ url: 'stun:stun.softjoys.com' },
|
|
{ url: 'stun:stun.voiparound.com' },
|
|
{ url: 'stun:stun.voipbuster.com' },
|
|
{ url: 'stun:stun.voipstunt.com' },
|
|
{ url: 'stun:stun.voxgratia.org' },
|
|
{ url: 'stun:stun.xten.com' },
|
|
|
|
// {
|
|
// url: 'turn:numb.viagenie.ca',
|
|
// credential: 'muazkh',
|
|
// username: 'webrtc@live.com',
|
|
// },
|
|
// {
|
|
// url: 'turn:192.158.29.39:3478?transport=udp',
|
|
// credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
|
|
// username: '28224511:1379330808',
|
|
// },
|
|
// {
|
|
// url: 'turn:192.158.29.39:3478?transport=tcp',
|
|
// credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
|
|
// username: '28224511:1379330808',
|
|
// },
|
|
],
|
|
};
|
|
|
|
const pcConstraints = {
|
|
optional: [{ DtlsSrtpKeyAgreement: true }],
|
|
};
|
|
|
|
export interface RTCPeerProps {
|
|
channelName: string;
|
|
offer?: RTCSessionDescriptionInit;
|
|
sendAnswer: (offer: RTCSessionDescriptionInit) => void;
|
|
sendOffer: (offer: RTCSessionDescriptionInit) => void;
|
|
}
|
|
|
|
export default class RTCPeer {
|
|
channelName: string;
|
|
peerConnection: RTCPeerConnection;
|
|
channel: RTCDataChannel;
|
|
|
|
sendAnswer: (offer: RTCSessionDescriptionInit) => void;
|
|
sendOffer: (offer: RTCSessionDescriptionInit) => void;
|
|
|
|
constructor({ channelName, offer, sendAnswer, sendOffer }: RTCPeerProps) {
|
|
this.sendOffer = sendOffer;
|
|
this.sendAnswer = sendAnswer;
|
|
this.channelName = channelName;
|
|
|
|
this.peerConnection = new RTCPeerConnection(); //(servers, pcConstraints);
|
|
this.peerConnection.onicecandidate = offer
|
|
? this.#handleIceCandidateAnswer
|
|
: this.#handleIceCandidateOffer;
|
|
|
|
this.#createDataChannel();
|
|
|
|
if (offer) {
|
|
console.log('answer');
|
|
this.peerConnection.setRemoteDescription(offer);
|
|
this.peerConnection.createAnswer().then((answer) => {
|
|
this.peerConnection.setLocalDescription(answer);
|
|
});
|
|
} else {
|
|
console.log('call');
|
|
this.peerConnection.createOffer().then((offer) => {
|
|
this.peerConnection.setLocalDescription(offer);
|
|
});
|
|
}
|
|
}
|
|
|
|
onAnswer = (answer: RTCSessionDescriptionInit) => {
|
|
this.peerConnection.setRemoteDescription(answer);
|
|
};
|
|
|
|
#handleIceCandidateAnswer = (event: RTCPeerConnectionIceEvent) => {
|
|
if (!event.candidate) {
|
|
const answer = this.peerConnection.localDescription;
|
|
|
|
console.log('send-answer', { answer });
|
|
if (answer) {
|
|
this.sendAnswer(answer);
|
|
}
|
|
}
|
|
};
|
|
|
|
#handleIceCandidateOffer = (event: RTCPeerConnectionIceEvent) => {
|
|
if (!event.candidate) {
|
|
const offer = this.peerConnection.localDescription;
|
|
|
|
if (offer) {
|
|
console.log('send-offer', { offer });
|
|
this.sendOffer(offer);
|
|
}
|
|
}
|
|
};
|
|
|
|
#createDataChannel = () => {
|
|
try {
|
|
this.channel = this.peerConnection.createDataChannel(this.channelName);
|
|
|
|
this.channel.onopen = () => {
|
|
console.log('Receive Channel[onopen]:', this.channel.readyState);
|
|
};
|
|
|
|
this.channel.onmessage = (event: MessageEvent) => {
|
|
console.log('Receive Channel[onmessage]:', event.data);
|
|
};
|
|
|
|
this.channel.onclose = () => {
|
|
console.log('Receive Channel[onclose]:', this.channel.readyState);
|
|
};
|
|
} catch (error) {
|
|
console.error('[RTCPeer|#createDataChannel] ERROR', error);
|
|
}
|
|
};
|
|
}
|