WebRTC and WebSocket merged
This commit is contained in:
		
							parent
							
								
									d3142c3ee4
								
							
						
					
					
						commit
						7dd4797f00
					
				| 
						 | 
				
			
			@ -1,34 +1,79 @@
 | 
			
		|||
## Kurulum
 | 
			
		||||
 | 
			
		||||
Proje ortamına kurulumu
 | 
			
		||||
### Proje ortamına kurulumu
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="https://ws.saqut.com/script"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Geliştirme ortamına kurulumu
 | 
			
		||||
### Geliştirme ortamına kurulumu
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
const wsjs = new MWSE({
 | 
			
		||||
    endpoint: "https://ws.saqut.com/"    // Bağlanılacak sunucuyu belirtir
 | 
			
		||||
    endpoint: "https://ws.saqut.com/"    // MSWS kurulu sunucu adresi
 | 
			
		||||
});
 | 
			
		||||
wsjs.scope(async () => {
 | 
			
		||||
    // Bağlantı sağlandığında burası tetiklenir
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Kendi bağlantı kimliğini öğrenme
 | 
			
		||||
### Kendi bağlantı kimliğini öğrenme
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```javascript
 | 
			
		||||
wsjs.scope(async () => {
 | 
			
		||||
    let me = wsjs.peer('me');   // kendimizden bahsederken 'me' anahtar kelimesini kullanırız
 | 
			
		||||
    console.log(me.socketId);   // her peerin socketId'si olması gerekir
 | 
			
		||||
    let me = wsjs.peer('me');   // Kendi bağlantınız üzerinde işlem yaparken `me` olarak bahsedersiniz
 | 
			
		||||
    console.log(me.socketId);   // Her eşin tekil bir socketIdsi vardır
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Sanal Adres ayırma / yeniden ayırma / kaldırma
 | 
			
		||||
```javascript
 | 
			
		||||
wsjs.scope(async () => {
 | 
			
		||||
    let me = wsjs.peer('me');
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sanal adresler size veri gönderilmek istendiğinde veya etkileşime
 | 
			
		||||
     * geçilmesi istendiğinde ona socketId gibi bir UUID yerine sizi temsil eden daha kısa
 | 
			
		||||
     * ip adresi, sayı veya kısa bir kod ile aynı şeyleri yapmanıza olanak tanır.
 | 
			
		||||
     * Aynı anda hem sanal ip adres, sayı ve kısa koduna sahip olabilirsiniz
 | 
			
		||||
     * ancak aynı türden temsil koduna (mesela kısa koddan) birden fazla sahip olamazsınız
 | 
			
		||||
     * Yeni bir bağlantı daha açmanız gerekir
 | 
			
		||||
     **/
 | 
			
		||||
 | 
			
		||||
    // Bağlantınıze özel sanal tekil ip adresi kaynağı ayırın
 | 
			
		||||
    let ipadress = await me.virtualPressure.allocAPIPAddress();
 | 
			
		||||
 | 
			
		||||
    // Bağlantınıze özel sanal tekil numara kaynağı ayırın
 | 
			
		||||
    let numberaddress = await me.virtualPressure.allocAPNumber();
 | 
			
		||||
 | 
			
		||||
    // Bağlantınıze özel sanal kod kaynağı ayırın
 | 
			
		||||
    let shortcodeadress = await me.virtualPressure.allocAPShortCode();
 | 
			
		||||
 | 
			
		||||
    // Bütün bu kaynakları yenileriyle değiştirmek için
 | 
			
		||||
    // her birinin ayrı ayrı yeniden alma işlevleri vardır
 | 
			
		||||
    // Bir adresi yenilediğinizde artık eski adres kullanılmaz olur
 | 
			
		||||
    me.virtualPressure.reallocAPIPAddress();
 | 
			
		||||
    me.virtualPressure.reallocAPNumber();
 | 
			
		||||
    me.virtualPressure.reallocAPShortCode();
 | 
			
		||||
 | 
			
		||||
    // Bütün bu kaynakları kaldırmak için  her birinin ayrı ayrı
 | 
			
		||||
    // bırakma işlevi vardır
 | 
			
		||||
    // Bir adresi kullanmadığınızda artık bu adreslerden size
 | 
			
		||||
    // ulaşılamaz olursunuz
 | 
			
		||||
    await me.virtualPressure.releaseAPIPAddress();
 | 
			
		||||
    await me.virtualPressure.releaseAPNumber();
 | 
			
		||||
    await me.virtualPressure.releaseAPShortCode();
 | 
			
		||||
 | 
			
		||||
    await me.virtualPressure.queryAPIPAddress();
 | 
			
		||||
    await me.virtualPressure.queryAPNumber();
 | 
			
		||||
    await me.virtualPressure.queryAPShortCode();
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Farklı bir eş ile iletişime geçme
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```javascript
 | 
			
		||||
wsjs.scope(async () => {
 | 
			
		||||
    let peer = wsjs.peer('325a8f7f-eaaf-4c21-855e-9e965c0d5ac9')   // Diğer eşin socketId'sini belirtiyoruz
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import EventTarget from "./EventTarget";
 | 
			
		||||
import { PeerInfo } from "./PeerInfo";
 | 
			
		||||
import WebRTC from "./WebRTC";
 | 
			
		||||
import MWSE from "./index";
 | 
			
		||||
 | 
			
		||||
interface IPeerOptions{
 | 
			
		||||
| 
						 | 
				
			
			@ -15,12 +16,44 @@ export default class Peer extends EventTarget
 | 
			
		|||
    public selfSocket : boolean = false;
 | 
			
		||||
    public active : boolean = false;
 | 
			
		||||
    public info : PeerInfo;
 | 
			
		||||
    public rtc? : WebRTC;
 | 
			
		||||
    public peerConnection : boolean = false;
 | 
			
		||||
    public primaryChannel : "websocket" | "datachannel" = "datachannel";
 | 
			
		||||
    constructor(wsts:MWSE){
 | 
			
		||||
        super();
 | 
			
		||||
        this.mwse = wsts;
 | 
			
		||||
        this.info = new PeerInfo(this);
 | 
			
		||||
    }
 | 
			
		||||
    setPeerOptions(options: string | IPeerOptions){
 | 
			
		||||
    public createRTC() : WebRTC
 | 
			
		||||
    {
 | 
			
		||||
        this.rtc = new WebRTC();
 | 
			
		||||
        this.rtc.on("connected", () => {
 | 
			
		||||
            this.peerConnection = true;
 | 
			
		||||
        });
 | 
			
		||||
        this.rtc.on('disconnected', () => {
 | 
			
		||||
            this.peerConnection = false;
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.on("output",(payload:object) => {
 | 
			
		||||
            this.send({
 | 
			
		||||
                type: 'rtc:session',
 | 
			
		||||
                payload: payload
 | 
			
		||||
            })
 | 
			
		||||
        });
 | 
			
		||||
        this.on('message',(data:{type?:string,payload?:any}) => {
 | 
			
		||||
            if(data.type == 'rtc:session')
 | 
			
		||||
            {
 | 
			
		||||
                if(this.rtc)
 | 
			
		||||
                {
 | 
			
		||||
                    this.rtc.emit("input", data.payload)
 | 
			
		||||
                }
 | 
			
		||||
            }else if(data.type == 'rtc:message')
 | 
			
		||||
            {
 | 
			
		||||
                this.emit("message", data.payload)
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return this.rtc;
 | 
			
		||||
    }
 | 
			
		||||
    public setPeerOptions(options: string | IPeerOptions){
 | 
			
		||||
        if(typeof options == "string")
 | 
			
		||||
        {
 | 
			
		||||
            this.setSocketId(options)
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +61,7 @@ export default class Peer extends EventTarget
 | 
			
		|||
            this.options = options;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    setSocketId(uuid: string){
 | 
			
		||||
    public setSocketId(uuid: string){
 | 
			
		||||
        this.socketId = uuid;
 | 
			
		||||
    }
 | 
			
		||||
    async metadata() : Promise<any>
 | 
			
		||||
| 
						 | 
				
			
			@ -77,11 +110,37 @@ export default class Peer extends EventTarget
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
    async send(pack: any){
 | 
			
		||||
        await this.mwse.EventPooling.request({
 | 
			
		||||
            type:'pack/to',
 | 
			
		||||
            pack,
 | 
			
		||||
            to: this.socketId
 | 
			
		||||
        });
 | 
			
		||||
        let isOpenedP2P = this.peerConnection;
 | 
			
		||||
        let isOpenedServer = this.mwse.server.connected;
 | 
			
		||||
        let sendChannel : "websocket" | "datachannel";
 | 
			
		||||
        if(isOpenedP2P && isOpenedServer)
 | 
			
		||||
        {
 | 
			
		||||
            if(this.primaryChannel == "websocket")
 | 
			
		||||
            {
 | 
			
		||||
                sendChannel = "websocket"
 | 
			
		||||
            }else
 | 
			
		||||
            {
 | 
			
		||||
                sendChannel = "datachannel"
 | 
			
		||||
            }
 | 
			
		||||
        }else if(isOpenedServer){
 | 
			
		||||
            sendChannel = "websocket"
 | 
			
		||||
        }else{
 | 
			
		||||
            sendChannel = "datachannel"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(sendChannel == "websocket")
 | 
			
		||||
        {
 | 
			
		||||
            await this.mwse.EventPooling.request({
 | 
			
		||||
                type:'pack/to',
 | 
			
		||||
                pack,
 | 
			
		||||
                to: this.socketId
 | 
			
		||||
            });
 | 
			
		||||
        }else{
 | 
			
		||||
            this.rtc?.send({
 | 
			
		||||
                type: 'rtc:message',
 | 
			
		||||
                payload: pack
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    async forget(){
 | 
			
		||||
        this.mwse.peers.delete(this.socketId as string);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,378 @@
 | 
			
		|||
interface TransferStreamInfo
 | 
			
		||||
{
 | 
			
		||||
    senders : RTCRtpSender[];
 | 
			
		||||
    stream:MediaStream | undefined;
 | 
			
		||||
    id:string;
 | 
			
		||||
    name:string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class WebRTC
 | 
			
		||||
{
 | 
			
		||||
    public static channels : Map<any,any> = new Map();
 | 
			
		||||
    public static requireGC : boolean = false;
 | 
			
		||||
    public id : any;
 | 
			
		||||
    public active : boolean = false;
 | 
			
		||||
    public connectionStatus : "closed" | "connected" | "connecting" | "disconnected" | "failed" | "new" = "new";
 | 
			
		||||
    public iceStatus : "checking" | "closed" | "completed" | "connected" | "disconnected" | "failed" | "new" = "new";
 | 
			
		||||
    public gatheringStatus : "complete" | "gathering" | "new" = "new";
 | 
			
		||||
    public signalingStatus : "" | "closed" | "have-local-offer" | "have-local-pranswer" | "have-remote-offer" | "have-remote-pranswer" | "stable" = ""
 | 
			
		||||
    public rtc! : RTCPeerConnection;
 | 
			
		||||
    public recaivingStream : Map<string, TransferStreamInfo> = new Map();
 | 
			
		||||
    public sendingStream : Map<string, TransferStreamInfo> = new Map();
 | 
			
		||||
    public events : { [eventname:string]: Function[] } = {};
 | 
			
		||||
    public channel : RTCDataChannel | undefined;
 | 
			
		||||
 | 
			
		||||
    public WebRTC()
 | 
			
		||||
    {
 | 
			
		||||
        this.rtc = new RTCPeerConnection({
 | 
			
		||||
            iceCandidatePoolSize: 0,
 | 
			
		||||
            iceTransportPolicy:"all",
 | 
			
		||||
            rtcpMuxPolicy:"require",
 | 
			
		||||
            iceServers:[{
 | 
			
		||||
                urls: "stun:stun.l.google.com:19302"
 | 
			
		||||
            },{
 | 
			
		||||
                urls: "stun:stun1.l.google.com:19302"
 | 
			
		||||
            },{
 | 
			
		||||
                urls: "stun:stun2.l.google.com:19302"
 | 
			
		||||
            },{
 | 
			
		||||
                urls: "stun:stun3.l.google.com:19302"
 | 
			
		||||
            },{
 | 
			
		||||
                urls: "stun:stun4.l.google.com:19302"
 | 
			
		||||
            }]
 | 
			
		||||
        });
 | 
			
		||||
        this.rtc.addEventListener("connectionstatechange",()=>{
 | 
			
		||||
            this.eventConnectionState();
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("icecandidate",(...args)=>{
 | 
			
		||||
            this.eventIcecandidate(...args);
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("iceconnectionstatechange",()=>{
 | 
			
		||||
            this.eventICEConnectionState();
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("icegatheringstatechange",()=>{
 | 
			
		||||
            this.eventICEGatherinState();
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("negotiationneeded",()=>{
 | 
			
		||||
            this.eventNogationNeeded();
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("signalingstatechange",()=>{
 | 
			
		||||
            this.eventSignalingState();
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("track",(...args)=>{
 | 
			
		||||
            this.eventTrack(...args);
 | 
			
		||||
        })
 | 
			
		||||
        this.rtc.addEventListener("datachannel",(...args)=>{
 | 
			
		||||
            this.eventDatachannel(...args);
 | 
			
		||||
        })
 | 
			
		||||
        this.on('input',async (data:{[key:string]:any})=>{
 | 
			
		||||
            switch(data.type)
 | 
			
		||||
            {
 | 
			
		||||
                case "icecandidate":{
 | 
			
		||||
                    await this.rtc.addIceCandidate(new RTCIceCandidate(data.value));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "offer":{
 | 
			
		||||
                    await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value));
 | 
			
		||||
                    let answer = await this.rtc.createAnswer({
 | 
			
		||||
                        offerToReceiveAudio: true,
 | 
			
		||||
                        offerToReceiveVideo: true
 | 
			
		||||
                    })
 | 
			
		||||
                    await this.rtc.setLocalDescription(answer);
 | 
			
		||||
                    this.send({
 | 
			
		||||
                        type: 'answer',
 | 
			
		||||
                        value: answer
 | 
			
		||||
                    });
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "answer":{
 | 
			
		||||
                    await this.rtc.setRemoteDescription(new RTCSessionDescription(data.value))
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "streamInfo":{
 | 
			
		||||
                    let {id,value} = data;
 | 
			
		||||
                    let streamInfo = this.recaivingStream.get(id);
 | 
			
		||||
                    if(!streamInfo)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.recaivingStream.set(id,value as TransferStreamInfo);
 | 
			
		||||
                    }else{
 | 
			
		||||
                        this.recaivingStream.set(id,{
 | 
			
		||||
                            ...streamInfo,
 | 
			
		||||
                            ...value
 | 
			
		||||
                        } as TransferStreamInfo);
 | 
			
		||||
                    }
 | 
			
		||||
                    this.send({
 | 
			
		||||
                        type:'streamAccept',
 | 
			
		||||
                        id
 | 
			
		||||
                    })
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "streamRemoved":{
 | 
			
		||||
                    let {id} = data;
 | 
			
		||||
                    this.emit('stream:stopped', this.recaivingStream.get(id));
 | 
			
		||||
                    this.sendingStream.delete(id);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "streamAccept":{
 | 
			
		||||
                    let {id} = data;
 | 
			
		||||
                    let {stream} = this.sendingStream.get(id) as {stream:MediaStream};
 | 
			
		||||
                    let senders = [];
 | 
			
		||||
                    for (const track of stream.getTracks()) {
 | 
			
		||||
                        senders.push(this.rtc.addTrack(track, stream));
 | 
			
		||||
                    };
 | 
			
		||||
                    stream.senders = senders;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "message":{
 | 
			
		||||
                    this.emit('message', data.payload);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    public addEventListener(event:string,callback: Function){
 | 
			
		||||
        (this.events[event] || (this.events[event]=[])).push(callback);
 | 
			
		||||
    };
 | 
			
		||||
    public on(event:string,callback: Function){
 | 
			
		||||
        this.addEventListener(event, callback)
 | 
			
		||||
    };
 | 
			
		||||
    public async dispatch(event:string,...args:any[]) : Promise<any> {
 | 
			
		||||
        if(this.events[event])
 | 
			
		||||
        {
 | 
			
		||||
            for (const callback of this.events[event])
 | 
			
		||||
            {
 | 
			
		||||
                await callback(...args)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public async emit(event:string,...args:any[]) : Promise<any> {
 | 
			
		||||
        await this.dispatch(event, ...args)
 | 
			
		||||
    }
 | 
			
		||||
    public connect()
 | 
			
		||||
    {
 | 
			
		||||
        if(!this.channel)
 | 
			
		||||
        {
 | 
			
		||||
            this.createDefaultDataChannel();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public sendMessage(data: any)
 | 
			
		||||
    {
 | 
			
		||||
        this.send({
 | 
			
		||||
            type: 'message',
 | 
			
		||||
            payload: data
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    public createDefaultDataChannel()
 | 
			
		||||
    {
 | 
			
		||||
        let dt = this.rtc.createDataChannel(':default:',{
 | 
			
		||||
            ordered: true
 | 
			
		||||
        });
 | 
			
		||||
        dt.addEventListener("open",()=>{
 | 
			
		||||
            this.channel = dt;
 | 
			
		||||
            WebRTC.channels.set(this.id, this);
 | 
			
		||||
        });
 | 
			
		||||
        dt.addEventListener("message",({data})=>{
 | 
			
		||||
            let pack = JSON.parse(data);
 | 
			
		||||
            this.emit('input', pack);
 | 
			
		||||
        })
 | 
			
		||||
        dt.addEventListener("close",()=>{
 | 
			
		||||
            this.channel = undefined;
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    public destroy()
 | 
			
		||||
    {
 | 
			
		||||
        this.active = false;
 | 
			
		||||
        if(this.channel)
 | 
			
		||||
        {
 | 
			
		||||
            this.channel.close();
 | 
			
		||||
            this.channel = undefined;
 | 
			
		||||
        }
 | 
			
		||||
        if(this.rtc)
 | 
			
		||||
        {
 | 
			
		||||
            this.rtc.close();
 | 
			
		||||
            // this.rtc = undefined;
 | 
			
		||||
        };
 | 
			
		||||
        this.emit('disconnected');
 | 
			
		||||
        WebRTC.channels.delete(this.id);
 | 
			
		||||
    }
 | 
			
		||||
    public eventDatachannel(event: RTCDataChannelEvent)
 | 
			
		||||
    {
 | 
			
		||||
        if(event.channel.label == ':default:'){
 | 
			
		||||
            WebRTC.channels.set(this.id, this);
 | 
			
		||||
            this.channel = event.channel
 | 
			
		||||
        }
 | 
			
		||||
        event.channel.addEventListener("message",({data})=>{
 | 
			
		||||
            let pack = JSON.parse(data);
 | 
			
		||||
            this.emit('input', pack);
 | 
			
		||||
        })
 | 
			
		||||
        event.channel.addEventListener("close",()=>{
 | 
			
		||||
            this.channel = undefined;
 | 
			
		||||
            WebRTC.channels.delete(this.id);
 | 
			
		||||
            WebRTC.requireGC = true;
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    public send(data:object)
 | 
			
		||||
    {
 | 
			
		||||
        if(this.channel?.readyState == "open")
 | 
			
		||||
        {
 | 
			
		||||
            this.channel.send(JSON.stringify(data));
 | 
			
		||||
        }else{
 | 
			
		||||
            this.emit('output', data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public eventConnectionState()
 | 
			
		||||
    {
 | 
			
		||||
        this.connectionStatus = this.rtc.connectionState;
 | 
			
		||||
        if(this.connectionStatus == 'connected')
 | 
			
		||||
        {
 | 
			
		||||
            if(this.active == false)
 | 
			
		||||
            {
 | 
			
		||||
                this.emit('connected');
 | 
			
		||||
                this.active = true;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if(this.connectionStatus == 'failed' || this.connectionStatus == "disconnected" || this.connectionStatus == "closed")
 | 
			
		||||
        {
 | 
			
		||||
            if(this.active)
 | 
			
		||||
            {
 | 
			
		||||
                this.destroy();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public eventIcecandidate(event: RTCPeerConnectionIceEvent)
 | 
			
		||||
    {
 | 
			
		||||
        if(event.candidate)
 | 
			
		||||
        {
 | 
			
		||||
            this.send({
 | 
			
		||||
                type:'icecandidate',
 | 
			
		||||
                value: event.candidate
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public eventICEConnectionState()
 | 
			
		||||
    {
 | 
			
		||||
        this.iceStatus = this.rtc.iceConnectionState;
 | 
			
		||||
    }
 | 
			
		||||
    public eventICEGatherinState()
 | 
			
		||||
    {
 | 
			
		||||
        this.gatheringStatus = this.rtc.iceGatheringState;
 | 
			
		||||
    }
 | 
			
		||||
    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
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    public eventSignalingState()
 | 
			
		||||
    {
 | 
			
		||||
        this.signalingStatus = this.rtc.signalingState;
 | 
			
		||||
    }
 | 
			
		||||
    public eventTrack(event: RTCTrackEvent)
 | 
			
		||||
    {
 | 
			
		||||
        if(event.streams.length)
 | 
			
		||||
        {
 | 
			
		||||
            for (const stream of event.streams) {
 | 
			
		||||
                if((this.recaivingStream.get(stream.id) as {stream : MediaStream | undefined}).stream == null)
 | 
			
		||||
                {
 | 
			
		||||
                    (
 | 
			
		||||
                        this.recaivingStream.get(stream.id) as {stream : MediaStream | undefined}
 | 
			
		||||
                    ).stream = stream;
 | 
			
		||||
                    this.emit('stream:added', this.recaivingStream.get(stream.id));
 | 
			
		||||
                }else{
 | 
			
		||||
                    (
 | 
			
		||||
                        this.recaivingStream.get(stream.id) as {stream : MediaStream | undefined}
 | 
			
		||||
                    ).stream = stream;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public sendStream(stream:MediaStream,name:string,info:{[key:string]:any}){
 | 
			
		||||
        this.send({
 | 
			
		||||
            type: 'streamInfo',
 | 
			
		||||
            id: stream.id,
 | 
			
		||||
            value: {
 | 
			
		||||
                ...info,
 | 
			
		||||
                name: name
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        this.sendingStream.set(stream.id,{
 | 
			
		||||
            ...info,
 | 
			
		||||
            id:stream.id,
 | 
			
		||||
            name: name,
 | 
			
		||||
            stream
 | 
			
		||||
        } as TransferStreamInfo);
 | 
			
		||||
    };
 | 
			
		||||
    public stopStream(_stream:MediaStream){
 | 
			
		||||
        if(this.connectionStatus != 'connected'){
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        if(this.sendingStream.has(_stream.id))
 | 
			
		||||
        {
 | 
			
		||||
            let {stream} = this.sendingStream.get(_stream.id) as {stream:MediaStream};
 | 
			
		||||
    
 | 
			
		||||
            for (const track of stream.getTracks()) {
 | 
			
		||||
                for (const RTCPSender of this.rtc.getSenders()) {
 | 
			
		||||
                    if(RTCPSender.track?.id == track.id)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.rtc.removeTrack(RTCPSender);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
            this.send({
 | 
			
		||||
                type: 'streamRemoved',
 | 
			
		||||
                id: stream.id
 | 
			
		||||
            });
 | 
			
		||||
            this.sendingStream.delete(_stream.id)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public stopAllStreams()
 | 
			
		||||
    {
 | 
			
		||||
        if(this.connectionStatus != 'connected'){
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        for (const [id, {stream}] of  this.sendingStream) {
 | 
			
		||||
            if(stream == undefined)
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            for (const track of stream.getTracks()) {
 | 
			
		||||
                for (const RTCPSender of this.rtc.getSenders()) {
 | 
			
		||||
                    if(RTCPSender.track?.id == track.id)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.rtc.removeTrack(RTCPSender);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this.send({
 | 
			
		||||
                type: 'streamRemoved',
 | 
			
		||||
                id: stream.id
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
    
 | 
			
		||||
        this.sendingStream.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WebRTC.requireGC = false;
 | 
			
		||||
setInterval(()=>{
 | 
			
		||||
    if(WebRTC.requireGC == false) return;
 | 
			
		||||
    let img = document.createElement("img");
 | 
			
		||||
    img.src = window.URL.createObjectURL(new Blob([new ArrayBuffer(5e+7)]));
 | 
			
		||||
    img.onerror = function() {
 | 
			
		||||
        window.URL.revokeObjectURL(this.src);
 | 
			
		||||
    };
 | 
			
		||||
    WebRTC.requireGC = false;
 | 
			
		||||
}, 3000)
 | 
			
		||||
 | 
			
		||||
declare global {
 | 
			
		||||
    interface MediaStream {
 | 
			
		||||
        senders : RTCRtpSender[];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,9 @@ import { IPPressure } from "./IPPressure";
 | 
			
		|||
import Peer from "./Peer";
 | 
			
		||||
import Room, { IRoomOptions } from "./Room";
 | 
			
		||||
import WSTSProtocol, { Message } from "./WSTSProtocol";
 | 
			
		||||
import WebRTC from "./WebRTC";
 | 
			
		||||
export default class MWSE extends EventTarget {
 | 
			
		||||
    public static rtc : WebRTC;
 | 
			
		||||
    public server! : Connection;
 | 
			
		||||
    public WSTSProtocol! : WSTSProtocol;
 | 
			
		||||
    public EventPooling! : EventPool;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>Document</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <script src="http://127.0.0.1:7707/script"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
        const wsjs = new MWSE({
 | 
			
		||||
            endpoint: "ws://127.0.0.1:7707"
 | 
			
		||||
        });
 | 
			
		||||
        wsjs.scope(async () => {
 | 
			
		||||
            let me = wsjs.peer('me');
 | 
			
		||||
 | 
			
		||||
            await me.info.set("name","Abdussamed");
 | 
			
		||||
            await me.info.set("surname","ULUTAŞ");
 | 
			
		||||
            await me.info.set("age","25");
 | 
			
		||||
            await me.info.set("date",1);
 | 
			
		||||
 | 
			
		||||
            let t = 2;
 | 
			
		||||
            setInterval(()=>{
 | 
			
		||||
                me.info.set("date", t);
 | 
			
		||||
                t++;
 | 
			
		||||
            },2000)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            let room = wsjs.room({
 | 
			
		||||
                name: "saqut.com",
 | 
			
		||||
                description: "saqut.com try",
 | 
			
		||||
                joinType: "free",
 | 
			
		||||
                ifexistsJoin: true,
 | 
			
		||||
                accessType: "private",
 | 
			
		||||
                notifyActionInvite: false,
 | 
			
		||||
                notifyActionJoined: true,
 | 
			
		||||
                notifyActionEjected: true
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            await room.createRoom();
 | 
			
		||||
 | 
			
		||||
            let peers = await room.fetchPeers();
 | 
			
		||||
            for (const peer of peers) {
 | 
			
		||||
                await peer.info.fetch();
 | 
			
		||||
                console.log("Peer info fetched",peer.socketId,peer.info.get());
 | 
			
		||||
                peer.on('info', (name, value) => {
 | 
			
		||||
                    console.log("Peer info changed", peer.socketId, name, value, peer.info.get());
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            room.on('join', async peer => {
 | 
			
		||||
                await peer.info.fetch();
 | 
			
		||||
                console.log("Peer info fetched",peer.socketId,peer.info.get());
 | 
			
		||||
                peer.on('info', (name, value) => {
 | 
			
		||||
                    console.log("Peer info changed", peer.socketId, name, value, peer.info.get());
 | 
			
		||||
                })
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
		Loading…
	
		Reference in New Issue