Merge pull request 'perfectnogation' (#20) from perfectnogation into stable
Reviewed-on: #20
This commit is contained in:
commit
41b7a052ab
|
@ -7,7 +7,7 @@ addListener('disconnect',(global, xclient)=>{
|
||||||
{
|
{
|
||||||
client?.send([
|
client?.send([
|
||||||
{
|
{
|
||||||
id: clientid
|
id: xclient.id
|
||||||
},
|
},
|
||||||
"peer/disconnect"
|
"peer/disconnect"
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
import MWSE from "frontend";
|
||||||
|
|
||||||
export interface IConnection{
|
export interface IConnection{
|
||||||
endpoint: string;
|
endpoint: string;
|
||||||
autoReconnect?: boolean | {
|
autoReconnect?: boolean | {
|
||||||
timeout: number;
|
timeout: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
|
|
||||||
export class Connection
|
export class Connection
|
||||||
{
|
{
|
||||||
public ws! : WebSocket;
|
public ws! : WebSocket;
|
||||||
|
@ -16,10 +16,11 @@ export class Connection
|
||||||
public autoReconnect : boolean = true;
|
public autoReconnect : boolean = true;
|
||||||
public autoReconnectTimeout : number = 3000;
|
public autoReconnectTimeout : number = 3000;
|
||||||
public autoReconnectTimer? : number;
|
public autoReconnectTimer? : number;
|
||||||
constructor(options: IConnection){
|
constructor(mwse:MWSE, options: IConnection){
|
||||||
|
|
||||||
if(options.endpoint == "auto")
|
if(options.endpoint == "auto")
|
||||||
{
|
{
|
||||||
|
const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
|
||||||
let scriptPath = new URL(RootURL);
|
let scriptPath = new URL(RootURL);
|
||||||
let isSecurity = scriptPath.protocol == "https:";
|
let isSecurity = scriptPath.protocol == "https:";
|
||||||
let dumeUrl = scriptPath.pathname.split('/').slice(0,-1).join('/') + '/';
|
let dumeUrl = scriptPath.pathname.split('/').slice(0,-1).join('/') + '/';
|
||||||
|
@ -83,7 +84,7 @@ export class Connection
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
if(this.autoReconnect)
|
if(this.autoReconnect)
|
||||||
{
|
{
|
||||||
this.autoReconnectTimer = setTimeout(() => this.connect(), this.autoReconnectTimeout)
|
this.autoReconnectTimer = setTimeout(() => this.connect(), this.autoReconnectTimeout) as unknown as number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private eventError()
|
private eventError()
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import "webrtc-adapter";
|
|
||||||
import WebRTC from "./WebRTC";
|
import WebRTC from "./WebRTC";
|
||||||
import Peer from "./Peer";
|
import Peer from "./Peer";
|
||||||
|
|
||||||
|
|
|
@ -22,21 +22,18 @@ export default class Peer extends EventTarget
|
||||||
public selfSocket : boolean = false;
|
public selfSocket : boolean = false;
|
||||||
public active : boolean = false;
|
public active : boolean = false;
|
||||||
public info : PeerInfo;
|
public info : PeerInfo;
|
||||||
public rtc? : WebRTC;
|
public rtc : WebRTC;
|
||||||
public peerConnection : boolean = false;
|
public peerConnection : boolean = false;
|
||||||
public primaryChannel : "websocket" | "datachannel" = "datachannel";
|
public primaryChannel : "websocket" | "datachannel" = "datachannel";
|
||||||
constructor(wsts:MWSE){
|
constructor(wsts:MWSE){
|
||||||
super();
|
super();
|
||||||
this.mwse = wsts;
|
this.mwse = wsts;
|
||||||
|
this.rtc = this.createRTC();
|
||||||
this.info = new PeerInfo(this);
|
this.info = new PeerInfo(this);
|
||||||
this.on('pack',(data:{type?:string,action?:IMessageSymbase,payload?:any}) => {
|
this.on('pack',(data:{type?:string,action?:IMessageSymbase,payload?:any}) => {
|
||||||
if(data.type == ':rtcpack:')
|
if(data.type == ':rtcpack:')
|
||||||
{
|
{
|
||||||
if(this.rtc)
|
return this.rtc.emit("input", data.payload)
|
||||||
{
|
|
||||||
return this.rtc.emit("input", data.payload)
|
|
||||||
}
|
|
||||||
return console.warn("Not active rtc but recaived rtc packs")
|
|
||||||
};
|
};
|
||||||
this.emit("message", data);
|
this.emit("message", data);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import P2PFileSender from "./P2PFileSender";
|
import P2PFileSender from "./P2PFileSender";
|
||||||
import Peer from "./Peer";
|
import Peer from "./Peer";
|
||||||
import "webrtc-adapter";
|
|
||||||
interface TransferStreamInfo
|
interface TransferStreamInfo
|
||||||
{
|
{
|
||||||
senders : RTCRtpSender[];
|
senders : RTCRtpSender[];
|
||||||
|
@ -32,6 +31,12 @@ export default class WebRTC
|
||||||
rtcpMuxPolicy:"require",
|
rtcpMuxPolicy:"require",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public isPolite() : boolean
|
||||||
|
{
|
||||||
|
let myId = this.peer?.mwse.peer('me').socketId as string;
|
||||||
|
let peerId = this.peer?.socketId as string;
|
||||||
|
return myId < peerId;
|
||||||
|
}
|
||||||
|
|
||||||
public static defaultICEServers : RTCIceServer[] = [{
|
public static defaultICEServers : RTCIceServer[] = [{
|
||||||
urls: "stun:stun.l.google.com:19302"
|
urls: "stun:stun.l.google.com:19302"
|
||||||
|
@ -49,6 +54,13 @@ export default class WebRTC
|
||||||
|
|
||||||
public FileTransportChannel? : P2PFileSender;
|
public FileTransportChannel? : P2PFileSender;
|
||||||
|
|
||||||
|
public makingOffer = false;
|
||||||
|
public ignoreOffer = false;
|
||||||
|
public isSettingRemoteAnswerPending = false;
|
||||||
|
|
||||||
|
candicatePack : RTCIceCandidate[] = [];
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
rtcConfig?: RTCConfiguration,
|
rtcConfig?: RTCConfiguration,
|
||||||
rtcServers?: RTCIceServer[]
|
rtcServers?: RTCIceServer[]
|
||||||
|
@ -101,11 +113,40 @@ export default class WebRTC
|
||||||
switch(data.type)
|
switch(data.type)
|
||||||
{
|
{
|
||||||
case "icecandidate":{
|
case "icecandidate":{
|
||||||
await this.rtc.addIceCandidate(new RTCIceCandidate(data.value));
|
try{
|
||||||
|
if(this.rtc.remoteDescription){
|
||||||
|
await this.rtc.addIceCandidate(new RTCIceCandidate(data.value));
|
||||||
|
}else{
|
||||||
|
this.candicatePack.push(new RTCIceCandidate(data.value))
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
debugger;
|
||||||
|
}finally{
|
||||||
|
console.log("ICE Canbet")
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "offer":{
|
case "offer":{
|
||||||
|
let readyForOffer = !this.makingOffer && (this.rtc.signalingState == "stable" || this.isSettingRemoteAnswerPending);
|
||||||
|
|
||||||
|
const offerCollision = !readyForOffer;
|
||||||
|
|
||||||
|
this.ignoreOffer = !this.isPolite() && offerCollision;
|
||||||
|
|
||||||
|
if(this.ignoreOffer){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isSettingRemoteAnswerPending = false;
|
||||||
|
|
||||||
await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value));
|
await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value));
|
||||||
|
|
||||||
|
this.isSettingRemoteAnswerPending = false;
|
||||||
|
|
||||||
|
for (const candidate of this.candicatePack) {
|
||||||
|
await this.rtc.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
|
||||||
let answer = await this.rtc.createAnswer({
|
let answer = await this.rtc.createAnswer({
|
||||||
offerToReceiveAudio: true,
|
offerToReceiveAudio: true,
|
||||||
offerToReceiveVideo: true
|
offerToReceiveVideo: true
|
||||||
|
@ -119,6 +160,10 @@ export default class WebRTC
|
||||||
}
|
}
|
||||||
case "answer":{
|
case "answer":{
|
||||||
await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value))
|
await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value))
|
||||||
|
|
||||||
|
for (const candidate of this.candicatePack) {
|
||||||
|
await this.rtc.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "streamInfo":{
|
case "streamInfo":{
|
||||||
|
@ -270,7 +315,13 @@ export default class WebRTC
|
||||||
this.emit('connected');
|
this.emit('connected');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if(this.connectionStatus == 'failed' || this.connectionStatus == "disconnected" || this.connectionStatus == "closed")
|
|
||||||
|
if(this.connectionStatus == 'failed')
|
||||||
|
{
|
||||||
|
this.rtc.restartIce();
|
||||||
|
};
|
||||||
|
|
||||||
|
if(this.connectionStatus == "closed")
|
||||||
{
|
{
|
||||||
if(this.active)
|
if(this.active)
|
||||||
{
|
{
|
||||||
|
@ -298,16 +349,24 @@ export default class WebRTC
|
||||||
}
|
}
|
||||||
public async eventNogationNeeded()
|
public async eventNogationNeeded()
|
||||||
{
|
{
|
||||||
let offer = await this.rtc.createOffer({
|
try{
|
||||||
iceRestart: true,
|
this.makingOffer = true;
|
||||||
offerToReceiveAudio: true,
|
let offer = await this.rtc.createOffer({
|
||||||
offerToReceiveVideo: true
|
iceRestart: true,
|
||||||
});
|
offerToReceiveAudio: true,
|
||||||
await this.rtc.setLocalDescription(offer);
|
offerToReceiveVideo: true
|
||||||
this.send({
|
});
|
||||||
type: 'offer',
|
await this.rtc.setLocalDescription(offer);
|
||||||
value: offer
|
this.send({
|
||||||
});
|
type: 'offer',
|
||||||
|
value: offer
|
||||||
|
});
|
||||||
|
}catch(error){
|
||||||
|
console.error(`Nogation Error:`, error)
|
||||||
|
}
|
||||||
|
finally{
|
||||||
|
this.makingOffer = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public eventSignalingState()
|
public eventSignalingState()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,8 @@ export default class MWSE extends EventTarget {
|
||||||
}*/
|
}*/
|
||||||
constructor(options: IConnection){
|
constructor(options: IConnection){
|
||||||
super();
|
super();
|
||||||
this.server = new Connection(options);
|
MWSE.rtc = MWSE as unknown as WebRTC;
|
||||||
|
this.server = new Connection(this,options);
|
||||||
this.WSTSProtocol = new WSTSProtocol(this);
|
this.WSTSProtocol = new WSTSProtocol(this);
|
||||||
this.EventPooling = new EventPool(this);
|
this.EventPooling = new EventPool(this);
|
||||||
this.virtualPressure = new IPPressure(this);
|
this.virtualPressure = new IPPressure(this);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"description": "Mikro WebSocket Engine",
|
"description": "Mikro WebSocket Engine",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "parcel watch --no-hmr",
|
"compile": "parcel watch --no-hmr",
|
||||||
"build": "parcel build"
|
"build": "parcel build --no-optimize"
|
||||||
},
|
},
|
||||||
"source": "./frontend/index.ts",
|
"source": "./frontend/index.ts",
|
||||||
"targets": {
|
"targets": {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="index.js?v=42"></script>
|
<script src="./index.js?v=42"></script>
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -6,14 +6,6 @@ let mwse;
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
let mySocketId;
|
let mySocketId;
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
let myIPAddress;
|
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
let myNumber;
|
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +33,14 @@ function connect()
|
||||||
mwse = new MWSE({
|
mwse = new MWSE({
|
||||||
endpoint: "wss://ws.saqut.com"
|
endpoint: "wss://ws.saqut.com"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MWSE.rtc.defaultICEServers = [{
|
||||||
|
urls: "turn:20.166.82.187:3478",
|
||||||
|
username: "turnserver",
|
||||||
|
credential: "turnserver"
|
||||||
|
},{
|
||||||
|
urls: "stun:stun.l.google.com:19302"
|
||||||
|
}];
|
||||||
|
|
||||||
mwse.scope(beginEngine);
|
mwse.scope(beginEngine);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ function templateVideo(name, stream,infinitedMute)
|
||||||
<video autoplay playsinline muted data-name="${name}">
|
<video autoplay playsinline muted data-name="${name}">
|
||||||
|
|
||||||
</video>
|
</video>
|
||||||
<div class="tool-container">
|
<!--div class="tool-container">
|
||||||
<div class="tools">
|
<div class="tools">
|
||||||
<button>
|
<button>
|
||||||
<i class="material-icons">home</i>
|
<i class="material-icons">home</i>
|
||||||
|
@ -80,7 +80,7 @@ function templateVideo(name, stream,infinitedMute)
|
||||||
<i class="material-icons">close</i>
|
<i class="material-icons">close</i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div--->
|
||||||
</div>
|
</div>
|
||||||
`,"text/html");
|
`,"text/html");
|
||||||
|
|
||||||
|
@ -108,9 +108,9 @@ function addVideoList(name, stream, peer, infinitedMute)
|
||||||
|
|
||||||
function removeVideoList(name)
|
function removeVideoList(name)
|
||||||
{
|
{
|
||||||
if(videoContainer.querySelector(`[data-name="${name}"]`))
|
if(videoContainer.querySelector(`[data-user="${name}"]`))
|
||||||
{
|
{
|
||||||
let k = videoContainer.querySelector(`[data-name="${name}"]`);
|
let k = videoContainer.querySelector(`[data-user="${name}"]`);
|
||||||
if(k.dataset.user == activeVideo?.dataset.user || !activeVideo)
|
if(k.dataset.user == activeVideo?.dataset.user || !activeVideo)
|
||||||
{
|
{
|
||||||
activePeer = null;
|
activePeer = null;
|
||||||
|
@ -124,8 +124,6 @@ async function beginEngine()
|
||||||
let me = mwse.peer("me");
|
let me = mwse.peer("me");
|
||||||
me.disablePairAuth();
|
me.disablePairAuth();
|
||||||
mySocketId = me.socketId;
|
mySocketId = me.socketId;
|
||||||
myIPAddress = await mwse.virtualPressure.allocAPIPAddress();
|
|
||||||
myNumber = await mwse.virtualPressure.allocAPNumber();
|
|
||||||
|
|
||||||
let url = new URL(window.location);
|
let url = new URL(window.location);
|
||||||
roomid = url.searchParams.get("room");
|
roomid = url.searchParams.get("room");
|
||||||
|
@ -203,11 +201,13 @@ async function connectRoom()
|
||||||
});
|
});
|
||||||
await room.createRoom();
|
await room.createRoom();
|
||||||
|
|
||||||
room.on("join", peer => IncomingPeer(peer, true));
|
room.on("join", peer => IncomingPeer(peer,true));
|
||||||
room.on("eject", peer => OutgoingPeer(peer));
|
room.on("eject", peer => OutgoingPeer(peer));
|
||||||
|
|
||||||
for (const peer of await room.fetchPeers()) {
|
for (const peer of await room.fetchPeers()) {
|
||||||
IncomingPeer(peer)
|
if(peer.socketId != mwse.peer('me').socketId){
|
||||||
|
IncomingPeer(peer,false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true)
|
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true)
|
||||||
|
@ -219,21 +219,13 @@ async function connectRoom()
|
||||||
*/
|
*/
|
||||||
function IncomingPeer(peer,activeConnect)
|
function IncomingPeer(peer,activeConnect)
|
||||||
{
|
{
|
||||||
peer.createRTC({
|
|
||||||
iceCandidatePoolSize: 0
|
|
||||||
},[{
|
|
||||||
urls: "turn:20.166.82.187:3478",
|
|
||||||
username: "turnserver",
|
|
||||||
credential: "turnserver"
|
|
||||||
},{
|
|
||||||
urls: "stun:stun.l.google.com:19302"
|
|
||||||
}]);
|
|
||||||
if(activeConnect)
|
if(activeConnect)
|
||||||
{
|
{
|
||||||
peer.rtc.connect();
|
peer.rtc.connect();
|
||||||
}
|
}
|
||||||
peer.rtc.rtc.turboBitrate = 0;
|
peer.rtc.rtc.turboBitrate = 0;
|
||||||
peer.rtc.on('connected',() => {
|
peer.rtc.on('connected',() => {
|
||||||
|
console.log("Connected");
|
||||||
if(!activeConnect)
|
if(!activeConnect)
|
||||||
{
|
{
|
||||||
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
||||||
|
@ -241,6 +233,7 @@ function IncomingPeer(peer,activeConnect)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
peer.rtc.on('disconnected',() => {
|
peer.rtc.on('disconnected',() => {
|
||||||
|
console.log("Disconnected");
|
||||||
removeVideoList(peer.streamY, peer);
|
removeVideoList(peer.streamY, peer);
|
||||||
delete activePeers[peer.socketId];
|
delete activePeers[peer.socketId];
|
||||||
});
|
});
|
||||||
|
@ -258,7 +251,7 @@ function IncomingPeer(peer,activeConnect)
|
||||||
*/
|
*/
|
||||||
function OutgoingPeer(peer)
|
function OutgoingPeer(peer)
|
||||||
{
|
{
|
||||||
removeVideoList(peer.streamY, peer);
|
removeVideoList(peer.socketId, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
let relative;
|
let relative;
|
||||||
|
|
1417
script/index.js
1417
script/index.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue