perfectnogation #20
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -7,7 +7,7 @@ addListener('disconnect',(global, xclient)=>{
 | 
			
		|||
    {
 | 
			
		||||
        client?.send([
 | 
			
		||||
            {
 | 
			
		||||
                id: clientid
 | 
			
		||||
                id: xclient.id
 | 
			
		||||
            },
 | 
			
		||||
            "peer/disconnect"
 | 
			
		||||
        ])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
import MWSE from "frontend";
 | 
			
		||||
 | 
			
		||||
export interface IConnection{
 | 
			
		||||
    endpoint: string;
 | 
			
		||||
    autoReconnect?: boolean | {
 | 
			
		||||
        timeout: number;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
 | 
			
		||||
export class Connection
 | 
			
		||||
{
 | 
			
		||||
    public ws! : WebSocket;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +16,11 @@ export class Connection
 | 
			
		|||
    public autoReconnect : boolean = true;
 | 
			
		||||
    public autoReconnectTimeout : number = 3000;
 | 
			
		||||
    public autoReconnectTimer? : number;
 | 
			
		||||
    constructor(options: IConnection){
 | 
			
		||||
    constructor(mwse:MWSE, options: IConnection){
 | 
			
		||||
 | 
			
		||||
        if(options.endpoint == "auto")
 | 
			
		||||
        {
 | 
			
		||||
            const RootURL : string = ( <HTMLScriptElement> document.currentScript).src
 | 
			
		||||
            let scriptPath = new URL(RootURL);
 | 
			
		||||
            let isSecurity  = scriptPath.protocol == "https:";
 | 
			
		||||
            let dumeUrl = scriptPath.pathname.split('/').slice(0,-1).join('/') + '/';
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +84,7 @@ export class Connection
 | 
			
		|||
        this.connected = false;
 | 
			
		||||
        if(this.autoReconnect)
 | 
			
		||||
        {
 | 
			
		||||
            this.autoReconnectTimer = setTimeout(() => this.connect(), this.autoReconnectTimeout)
 | 
			
		||||
            this.autoReconnectTimer = setTimeout(() => this.connect(), this.autoReconnectTimeout) as unknown as number;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private eventError()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
import "webrtc-adapter";
 | 
			
		||||
import WebRTC from "./WebRTC";
 | 
			
		||||
import Peer from "./Peer";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,21 +22,18 @@ export default class Peer extends EventTarget
 | 
			
		|||
    public selfSocket : boolean = false;
 | 
			
		||||
    public active : boolean = false;
 | 
			
		||||
    public info : PeerInfo;
 | 
			
		||||
    public rtc? : WebRTC;
 | 
			
		||||
    public rtc : WebRTC;
 | 
			
		||||
    public peerConnection : boolean = false;
 | 
			
		||||
    public primaryChannel : "websocket" | "datachannel" = "datachannel";
 | 
			
		||||
    constructor(wsts:MWSE){
 | 
			
		||||
        super();
 | 
			
		||||
        this.mwse = wsts;
 | 
			
		||||
        this.rtc = this.createRTC();
 | 
			
		||||
        this.info = new PeerInfo(this);
 | 
			
		||||
        this.on('pack',(data:{type?:string,action?:IMessageSymbase,payload?:any}) => {
 | 
			
		||||
            if(data.type == ':rtcpack:')
 | 
			
		||||
            {
 | 
			
		||||
                if(this.rtc)
 | 
			
		||||
                {
 | 
			
		||||
                    return this.rtc.emit("input", data.payload)
 | 
			
		||||
                }
 | 
			
		||||
                return console.warn("Not active rtc but recaived rtc packs")
 | 
			
		||||
                return this.rtc.emit("input", data.payload)
 | 
			
		||||
            };
 | 
			
		||||
            this.emit("message", data);
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
import P2PFileSender from "./P2PFileSender";
 | 
			
		||||
import Peer from "./Peer";
 | 
			
		||||
import "webrtc-adapter";
 | 
			
		||||
interface TransferStreamInfo
 | 
			
		||||
{
 | 
			
		||||
    senders : RTCRtpSender[];
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +31,12 @@ export default class WebRTC
 | 
			
		|||
        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[] = [{
 | 
			
		||||
        urls: "stun:stun.l.google.com:19302"
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +54,13 @@ export default class WebRTC
 | 
			
		|||
 | 
			
		||||
    public FileTransportChannel? : P2PFileSender;
 | 
			
		||||
 | 
			
		||||
    public makingOffer = false;
 | 
			
		||||
    public ignoreOffer = false;
 | 
			
		||||
    public isSettingRemoteAnswerPending = false;
 | 
			
		||||
 | 
			
		||||
    candicatePack : RTCIceCandidate[] = [];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        rtcConfig?: RTCConfiguration,
 | 
			
		||||
        rtcServers?: RTCIceServer[]
 | 
			
		||||
| 
						 | 
				
			
			@ -101,11 +113,40 @@ export default class WebRTC
 | 
			
		|||
            switch(data.type)
 | 
			
		||||
            {
 | 
			
		||||
                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;
 | 
			
		||||
                }
 | 
			
		||||
                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));
 | 
			
		||||
 | 
			
		||||
                    this.isSettingRemoteAnswerPending = false;
 | 
			
		||||
 | 
			
		||||
                    for (const candidate of this.candicatePack) {
 | 
			
		||||
                        await this.rtc.addIceCandidate(candidate);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    let answer = await this.rtc.createAnswer({
 | 
			
		||||
                        offerToReceiveAudio: true,
 | 
			
		||||
                        offerToReceiveVideo: true
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +160,10 @@ export default class WebRTC
 | 
			
		|||
                }
 | 
			
		||||
                case "answer":{
 | 
			
		||||
                    await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value))
 | 
			
		||||
 | 
			
		||||
                    for (const candidate of this.candicatePack) {
 | 
			
		||||
                        await this.rtc.addIceCandidate(candidate);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "streamInfo":{
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +315,13 @@ export default class WebRTC
 | 
			
		|||
                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)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -298,16 +349,24 @@ export default class WebRTC
 | 
			
		|||
    }
 | 
			
		||||
    public async eventNogationNeeded()
 | 
			
		||||
    {
 | 
			
		||||
        let offer = await this.rtc.createOffer({
 | 
			
		||||
            iceRestart: true,
 | 
			
		||||
            offerToReceiveAudio: true,
 | 
			
		||||
            offerToReceiveVideo: true
 | 
			
		||||
        });
 | 
			
		||||
        await this.rtc.setLocalDescription(offer);
 | 
			
		||||
        this.send({
 | 
			
		||||
            type: 'offer',
 | 
			
		||||
            value: offer
 | 
			
		||||
        });
 | 
			
		||||
        try{
 | 
			
		||||
            this.makingOffer = true;
 | 
			
		||||
            let offer = await this.rtc.createOffer({
 | 
			
		||||
                iceRestart: true,
 | 
			
		||||
                offerToReceiveAudio: true,
 | 
			
		||||
                offerToReceiveVideo: true
 | 
			
		||||
            });
 | 
			
		||||
            await this.rtc.setLocalDescription(offer);
 | 
			
		||||
            this.send({
 | 
			
		||||
                type: 'offer',
 | 
			
		||||
                value: offer
 | 
			
		||||
            });
 | 
			
		||||
        }catch(error){
 | 
			
		||||
            console.error(`Nogation Error:`, error)
 | 
			
		||||
        }
 | 
			
		||||
        finally{
 | 
			
		||||
            this.makingOffer = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public eventSignalingState()
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,8 @@ export default class MWSE extends EventTarget {
 | 
			
		|||
    }*/
 | 
			
		||||
    constructor(options: IConnection){
 | 
			
		||||
        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.EventPooling = new EventPool(this);
 | 
			
		||||
        this.virtualPressure = new IPPressure(this);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
  "description": "Mikro WebSocket Engine",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "compile": "parcel watch --no-hmr",
 | 
			
		||||
    "build": "parcel build"
 | 
			
		||||
    "build": "parcel build --no-optimize"
 | 
			
		||||
  },
 | 
			
		||||
  "source": "./frontend/index.ts",
 | 
			
		||||
  "targets": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@
 | 
			
		|||
 | 
			
		||||
    </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">
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -6,14 +6,6 @@ let mwse;
 | 
			
		|||
 * @type {string}
 | 
			
		||||
 */
 | 
			
		||||
let mySocketId;
 | 
			
		||||
/**
 | 
			
		||||
 * @type {string}
 | 
			
		||||
 */
 | 
			
		||||
let myIPAddress;
 | 
			
		||||
/**
 | 
			
		||||
 * @type {string}
 | 
			
		||||
 */
 | 
			
		||||
let myNumber;
 | 
			
		||||
/**
 | 
			
		||||
 * @type {string}
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +33,14 @@ function connect()
 | 
			
		|||
    mwse = new MWSE({
 | 
			
		||||
        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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ function templateVideo(name, stream,infinitedMute)
 | 
			
		|||
            <video autoplay playsinline muted data-name="${name}">
 | 
			
		||||
            
 | 
			
		||||
            </video>
 | 
			
		||||
            <div class="tool-container">
 | 
			
		||||
            <!--div class="tool-container">
 | 
			
		||||
                <div class="tools">
 | 
			
		||||
                    <button>
 | 
			
		||||
                        <i class="material-icons">home</i>
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ function templateVideo(name, stream,infinitedMute)
 | 
			
		|||
                        <i class="material-icons">close</i>
 | 
			
		||||
                    </button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            </div--->
 | 
			
		||||
        </div>
 | 
			
		||||
    `,"text/html");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -108,9 +108,9 @@ function addVideoList(name, stream, peer, infinitedMute)
 | 
			
		|||
 | 
			
		||||
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)
 | 
			
		||||
        {
 | 
			
		||||
            activePeer = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,8 +124,6 @@ async function beginEngine()
 | 
			
		|||
    let me = mwse.peer("me");
 | 
			
		||||
    me.disablePairAuth();
 | 
			
		||||
    mySocketId = me.socketId;
 | 
			
		||||
    myIPAddress = await mwse.virtualPressure.allocAPIPAddress();
 | 
			
		||||
    myNumber = await mwse.virtualPressure.allocAPNumber();
 | 
			
		||||
 | 
			
		||||
    let url = new URL(window.location);
 | 
			
		||||
    roomid = url.searchParams.get("room");
 | 
			
		||||
| 
						 | 
				
			
			@ -203,11 +201,13 @@ async function connectRoom()
 | 
			
		|||
    });
 | 
			
		||||
    await room.createRoom();
 | 
			
		||||
    
 | 
			
		||||
    room.on("join", peer => IncomingPeer(peer, true));
 | 
			
		||||
    room.on("join", peer => IncomingPeer(peer,true));
 | 
			
		||||
    room.on("eject", peer => OutgoingPeer(peer));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -219,21 +219,13 @@ async function connectRoom()
 | 
			
		|||
 */
 | 
			
		||||
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)
 | 
			
		||||
    {
 | 
			
		||||
        peer.rtc.connect();
 | 
			
		||||
    }
 | 
			
		||||
    peer.rtc.rtc.turboBitrate = 0;
 | 
			
		||||
    peer.rtc.on('connected',() => {
 | 
			
		||||
        console.log("Connected");
 | 
			
		||||
        if(!activeConnect)
 | 
			
		||||
        {
 | 
			
		||||
            peer.rtc.sendStream(outgoingStream, "Webcam", {});
 | 
			
		||||
| 
						 | 
				
			
			@ -241,6 +233,7 @@ function IncomingPeer(peer,activeConnect)
 | 
			
		|||
        }
 | 
			
		||||
    });
 | 
			
		||||
    peer.rtc.on('disconnected',() => {
 | 
			
		||||
        console.log("Disconnected");
 | 
			
		||||
        removeVideoList(peer.streamY, peer);
 | 
			
		||||
        delete activePeers[peer.socketId];
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +251,7 @@ function IncomingPeer(peer,activeConnect)
 | 
			
		|||
 */
 | 
			
		||||
function OutgoingPeer(peer)
 | 
			
		||||
{
 | 
			
		||||
    removeVideoList(peer.streamY, peer);
 | 
			
		||||
    removeVideoList(peer.socketId, peer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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