예제 #1
0
        private IEnumerator setRemoteDesc(RTCSdpType type, string sdp)
        {
            var desc = new RTCSessionDescription
            {
                type = type,
                sdp  = sdp
            };

            OnLogEvent.Invoke($"SetRemoteDescription {type}", "");
            var opSetDesc = peer.SetRemoteDescription(ref desc);

            yield return(opSetDesc);

            if (opSetDesc.IsError)
            {
                OnErrorEvent.Invoke($"SetRemoteDescription {type}", opSetDesc.Error.message);
                yield break;
            }

            if (type == RTCSdpType.Offer)
            {
                yield return(CoroutineHandler.StartStaticCoroutine(sendDesc(RTCSdpType.Answer)));
            }
            else
            {
                OnOpen.Invoke();
            }
        }
        public RTCSessionDescription(RTCSdpType type, string sdp)
        {
            var strType = type.ToString().ToLower();
            var dict    = new Dictionary <string, string>();

            dict.Add("type", strType);
            dict.Add("sdp", sdp);
            this.HostObject = new HostObject("RTCSessionDescription", dict);
        }
 static void OnSuccessCreateSessionDesc(IntPtr ptr, RTCSdpType type, string sdp)
 {
     WebRTC.Sync(ptr, () =>
     {
         if (WebRTC.Table[ptr] is RTCPeerConnection connection)
         {
             connection.m_opSessionDesc.Desc = new RTCSessionDescription {
                 sdp = sdp, type = type
             };
             connection.m_opSessionDesc.Done();
         }
     });
 }
예제 #4
0
        private IEnumerator sendDesc(RTCSdpType type)
        {
            RTCSessionDescriptionAsyncOperation opCreate = null;

            if (type == RTCSdpType.Offer)
            {
                OnLogEvent.Invoke("CreateOffer()", "");
                opCreate = peer.CreateOffer(ref offerOption);
            }
            else
            {
                OnLogEvent.Invoke("CreateAnswer()", "");
                opCreate = peer.CreateAnswer(ref answerOptions);
            }

            yield return(opCreate);

            if (opCreate.IsError)
            {
                OnErrorEvent.Invoke($"Create {opCreate.Desc.type}", opCreate.Error.message);
                yield break;
            }
            else
            {
                OnLogEvent.Invoke($"Create {opCreate.Desc.type}", "");
            }

            if (opCreate.Desc.sdp == null)
            {
                OnErrorEvent.Invoke("opCreate.Desc.sdp is null", "");
                yield break;
            }
            else
            {
                OnLogEvent.Invoke($"SetLocalDescription {type}", $"{opCreate.Desc.sdp.Substring(0, 10)} ...");
            }
            var desc  = opCreate.Desc;
            var opSet = peer.SetLocalDescription(ref desc);

            yield return(opSet);

            if (opSet.IsError)
            {
                OnErrorEvent.Invoke($"SetLocalDescription {type}", opSet.Error.message);
                yield break;
            }

            OnLogEvent.Invoke($"Send {type}", "");
            signaling.SendDesc(streamId, desc.type.ToString().ToLower(), desc.sdp);
        }
    private IEnumerator createDesc(RTCSdpType type)
    {
        RTCSessionDescriptionAsyncOperation opCreate;

        if (type == RTCSdpType.Offer)
        {
            opCreate = peer.CreateOffer(ref offerOptions);
        }
        else
        {
            opCreate = peer.CreateAnswer(ref answerOptions);
        }

        yield return(opCreate);

        if (opCreate.IsError)
        {
            log(LogLevel.Error, $"Create {opCreate.Desc.type}: {opCreate.Error.message}");
            yield break;
        }
        else
        {
            log(LogLevel.Log, $"Create {opCreate.Desc.type}");
        }

        if (opCreate.Desc.sdp == null)
        {
            log(LogLevel.Error, $"opCreate.Desc.sdp is null");
            yield break;
        }
        else
        {
            log(LogLevel.Log, $"SetLocalDescription {type}: {opCreate.Desc.sdp}");
        }
        var desc  = opCreate.Desc;
        var opSet = peer.SetLocalDescription(ref desc);

        yield return(opSet);

        if (opSet.IsError)
        {
            log(LogLevel.Error, $"SetLocalDescription {type}: {opSet.Error.message}");
            yield break;
        }

        log(LogLevel.Log, $">>> Send \"takeConfiguration\" Command ({type}: '{desc.sdp.Substring(0, 10)} ...')");
        signaling.SendDesc(streamId, desc.type.ToString().ToLower(), desc.sdp);
    }
예제 #6
0
    IEnumerator CreateDescription(RTCSdpType type)
    {
        Debug.Log($"[Create {type}]");

        var op = type == RTCSdpType.Offer ? localConnection.CreateOffer(ref offerOption) : localConnection.CreateAnswer(ref answerOptions);

        yield return(op);

        if (op.IsError)
        {
            Debug.LogError(op.Error.message);
        }
        else
        {
            yield return(SetDescription(op.Desc, Side.Local));
        }
    }
    IEnumerator createDesc(string id, RTCSdpType type)
    {
        Debug.Log($"[Create {type}] id:{id}");
        var pc = pcs[id];
        var op = type == RTCSdpType.Offer ? pc.CreateOffer(ref offerOption) : pc.CreateAnswer(ref answerOptions);

        yield return(op);

        if (op.IsError)
        {
            Debug.LogError(op.Error.message);
        }
        else
        {
            yield return(setDesc(id, Side.Local, op.Desc));
        }
    }
    private IEnumerator setRemoteDesc(RTCSdpType type, string sdp)
    {
        var desc = new RTCSessionDescription
        {
            type = type,
            sdp  = sdp
        };

        log(LogLevel.Log, $"SetRemoteDescription {type}");
        var opSetDesc = peer.SetRemoteDescription(ref desc);

        yield return(opSetDesc);

        if (opSetDesc.IsError)
        {
            log(LogLevel.Error, $"SetRemoteDescription {type}: {opSetDesc.Error.message}");
            yield break;
        }

        if (type == RTCSdpType.Offer)
        {
            yield return(StartCoroutine(createDesc(RTCSdpType.Answer)));
        }
    }
예제 #9
0
        /// <summary>
        /// Handler for Signaller's OnMessageFromPeer event.
        /// </summary>
        /// <param name="peerId">ID of the peer.</param>
        /// <param name="message">Message from the peer.</param>
        private void Signaller_OnMessageFromPeer(int peerId, string message)
        {
            Task.Run(async() =>
            {
                Debug.Assert(_peerId == peerId || _peerId == -1);
                Debug.Assert(message.Length > 0);

                if (_peerId != peerId && _peerId != -1)
                {
                    Debug.WriteLine("[Error] Conductor: Received a message from unknown peer while already in a conversation with a different peer.");
                    return;
                }

                JsonObject jMessage;
                if (!JsonObject.TryParse(message, out jMessage))
                {
                    Debug.WriteLine("[Error] Conductor: Received unknown message." + message);
                    return;
                }

                string type = jMessage.ContainsKey(kSessionDescriptionTypeName) ? jMessage.GetNamedString(kSessionDescriptionTypeName) : null;
#if ORTCLIB
                bool created = false;
#endif
                if (_peerConnection == null)
                {
                    if (!IsNullOrEmpty(type))
                    {
                        // Create the peer connection only when call is
                        // about to get initiated. Otherwise ignore the
                        // messages from peers which could be a result
                        // of old (but not yet fully closed) connections.
                        if (type == "offer" || type == "answer" || type == "json")
                        {
                            Debug.Assert(_peerId == -1);
                            _peerId = peerId;

                            IEnumerable <Peer> enumerablePeer = Peers.Where(x => x.Id == peerId);
                            Peer = enumerablePeer.First();
#if ORTCLIB
                            created        = true;
                            _signalingMode = Helper.SignalingModeForClientName(Peer.Name);
#endif
                            _connectToPeerCancelationTokenSource = new CancellationTokenSource();
                            _connectToPeerTask = CreatePeerConnection(_connectToPeerCancelationTokenSource.Token);
                            bool connectResult = await _connectToPeerTask;
                            _connectToPeerTask = null;
                            _connectToPeerCancelationTokenSource.Dispose();
                            if (!connectResult)
                            {
                                Debug.WriteLine("[Error] Conductor: Failed to initialize our PeerConnection instance");
                                await Signaller.SignOut();
                                return;
                            }
                            else if (_peerId != peerId)
                            {
                                Debug.WriteLine("[Error] Conductor: Received a message from unknown peer while already in a conversation with a different peer.");
                                return;
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine("[Warn] Conductor: Received an untyped message after closing peer connection.");
                        return;
                    }
                }

                if (_peerConnection != null && !IsNullOrEmpty(type))
                {
                    if (type == "offer-loopback")
                    {
                        // Loopback not supported
                        Debug.Assert(false);
                    }
                    string sdp = null;
#if ORTCLIB
                    if (jMessage.ContainsKey(kSessionDescriptionJsonName))
                    {
                        var containerObject = new JsonObject {
                            { kSessionDescriptionJsonName, jMessage.GetNamedObject(kSessionDescriptionJsonName) }
                        };
                        sdp = containerObject.Stringify();
                    }
                    else if (jMessage.ContainsKey(kSessionDescriptionSdpName))
                    {
                        sdp = jMessage.GetNamedString(kSessionDescriptionSdpName);
                    }
#else
                    sdp = jMessage.ContainsKey(kSessionDescriptionSdpName) ? jMessage.GetNamedString(kSessionDescriptionSdpName) : null;
#endif
                    if (IsNullOrEmpty(sdp))
                    {
                        Debug.WriteLine("[Error] Conductor: Can't parse received session description message.");
                        return;
                    }

#if ORTCLIB
                    RTCSessionDescriptionSignalingType messageType = RTCSessionDescriptionSignalingType.SdpOffer;
                    switch (type)
                    {
                    case "json": messageType = RTCSessionDescriptionSignalingType.Json; break;

                    case "offer": messageType = RTCSessionDescriptionSignalingType.SdpOffer; break;

                    case "answer": messageType = RTCSessionDescriptionSignalingType.SdpAnswer; break;

                    case "pranswer": messageType = RTCSessionDescriptionSignalingType.SdpPranswer; break;

                    default: Debug.Assert(false, type); break;
                    }
#else
                    RTCSdpType messageType = RTCSdpType.Offer;
                    switch (type)
                    {
                    case "offer": messageType = RTCSdpType.Offer; break;

                    case "answer": messageType = RTCSdpType.Answer; break;

                    case "pranswer": messageType = RTCSdpType.Pranswer; break;

                    default: Debug.Assert(false, type); break;
                    }
#endif
                    Debug.WriteLine("Conductor: Received session description: " + message);
                    await _peerConnection.SetRemoteDescription(new RTCSessionDescription(messageType, sdp));

#if ORTCLIB
                    if ((messageType == RTCSessionDescriptionSignalingType.SdpOffer) ||
                        ((created) && (messageType == RTCSessionDescriptionSignalingType.Json)))
#else
                    if (messageType == RTCSdpType.Offer)
#endif
                    {
                        var answer = await _peerConnection.CreateAnswer();
                        await _peerConnection.SetLocalDescription(answer);
                        // Send answer
                        SendSdp(answer);
#if ORTCLIB
                        OrtcStatsManager.Instance.StartCallWatch(SessionId, false);
#endif
                    }
                }
                else
                {
                    RTCIceCandidate candidate = null;
#if ORTCLIB
                    if (RTCPeerConnectionSignalingMode.Json != _signalingMode)
#endif
                    {
                        var sdpMid = jMessage.ContainsKey(kCandidateSdpMidName)
                            ? jMessage.GetNamedString(kCandidateSdpMidName)
                            : null;
                        var sdpMlineIndex = jMessage.ContainsKey(kCandidateSdpMlineIndexName)
                            ? jMessage.GetNamedNumber(kCandidateSdpMlineIndexName)
                            : -1;
                        var sdp = jMessage.ContainsKey(kCandidateSdpName)
                            ? jMessage.GetNamedString(kCandidateSdpName)
                            : null;
                        //TODO: Check is this proper condition ((String.IsNullOrEmpty(sdpMid) && (sdpMlineIndex == -1)) || String.IsNullOrEmpty(sdp))
                        if (IsNullOrEmpty(sdpMid) || sdpMlineIndex == -1 || IsNullOrEmpty(sdp))
                        {
                            Debug.WriteLine("[Error] Conductor: Can't parse received message.\n" + message);
                            return;
                        }
#if ORTCLIB
                        candidate = IsNullOrEmpty(sdpMid) ? RTCIceCandidate.FromSdpStringWithMLineIndex(sdp, (ushort)sdpMlineIndex) : RTCIceCandidate.FromSdpStringWithMid(sdp, sdpMid);
#else
                        candidate = new RTCIceCandidate(sdp, sdpMid, (ushort)sdpMlineIndex);
#endif
                    }
#if ORTCLIB
                    else
                    {
                        candidate = RTCIceCandidate.FromJsonString(message);
                    }
                    _peerConnection?.AddIceCandidate(candidate);
#else
                    await _peerConnection.AddIceCandidate(candidate);
#endif


                    Debug.WriteLine("Conductor: Received candidate : " + message);
                }
            }).Wait();
        }
예제 #10
0
        public void MessageFromPeerTaskRun(int peerId, string content)
        {
            PeerId = peerId;

            Task.Run(async() =>
            {
                Debug.Assert(_peerId == PeerId || _peerId == -1);
                Debug.Assert(content.Length > 0);

                if (_peerId != PeerId && _peerId != -1)
                {
                    Debug.WriteLine("Received a message from unknown peer " +
                                    "while already in a conversation with a different peer.");

                    return;
                }

                if (!JsonObject.TryParse(content, out JsonObject jMessage))
                {
                    Debug.WriteLine($"Received unknown message: {content}");
                    return;
                }

                string type = jMessage.ContainsKey(NegotiationAtributes.Type)
                       ? jMessage.GetNamedString(NegotiationAtributes.Type)
                       : null;

                if (PeerConnection == null)
                {
                    if (!string.IsNullOrEmpty(type))
                    {
                        // Create the peer connection only when call is
                        // about to get initiated. Otherwise ignore the
                        // message from peers which could be result
                        // of old (but not yet fully closed) connections.
                        if (type == "offer" || type == "answer" || type == "json")
                        {
                            Debug.Assert(_peerId == -1);
                            _peerId = PeerId;

                            if (!CreatePeerConnection())
                            {
                                Debug.WriteLine("Failed to initialize our PeerConnection instance");

                                OnSignedOut.Invoke(this, null);
                                return;
                            }
                            else if (_peerId != PeerId)
                            {
                                Debug.WriteLine("Received a message from unknown peer while already " +
                                                "in a conversation with a different peer.");

                                return;
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine("[Warn] Received an untyped message after closing peer connection.");
                        return;
                    }
                }

                if (PeerConnection != null && !string.IsNullOrEmpty(type))
                {
                    if (type == "offer-loopback")
                    {
                        // Loopback not supported
                        Debug.Assert(false);
                    }

                    string sdp = null;

                    sdp = jMessage.ContainsKey(NegotiationAtributes.Sdp)
                          ? jMessage.GetNamedString(NegotiationAtributes.Sdp)
                          : null;

                    if (string.IsNullOrEmpty(sdp))
                    {
                        Debug.WriteLine("[Error] Can't parse received session description message.");
                        return;
                    }

                    Debug.WriteLine($"Received session description:\n{content}");

                    RTCSdpType messageType = RTCSdpType.Offer;
                    switch (type)
                    {
                    case "offer": messageType = RTCSdpType.Offer; break;

                    case "answer": messageType = RTCSdpType.Answer; break;

                    case "pranswer": messageType = RTCSdpType.Pranswer; break;

                    default: Debug.Assert(false, type); break;
                    }

                    var sdpInit     = new RTCSessionDescriptionInit();
                    sdpInit.Sdp     = sdp;
                    sdpInit.Type    = messageType;
                    var description = new RTCSessionDescription(sdpInit);

                    await PeerConnection.SetRemoteDescription(description);

                    if (messageType == RTCSdpType.Offer)
                    {
                        var answerOptions             = new RTCAnswerOptions();
                        IRTCSessionDescription answer = await PeerConnection.CreateAnswer(answerOptions);
                        await PeerConnection.SetLocalDescription(answer);
                        string jsonString = SdpToJsonString(answer);
                        // Send answer
                        OnSendMessageToRemotePeer.Invoke(this, jsonString);
                    }
                }
                else
                {
                    RTCIceCandidate candidate = null;

                    string sdpMid = jMessage.ContainsKey(NegotiationAtributes.SdpMid)
                           ? jMessage.GetNamedString(NegotiationAtributes.SdpMid)
                           : null;

                    double sdpMLineIndex = jMessage.ContainsKey(NegotiationAtributes.SdpMLineIndex)
                           ? jMessage.GetNamedNumber(NegotiationAtributes.SdpMLineIndex)
                           : -1;

                    string sdpCandidate = jMessage.ContainsKey(NegotiationAtributes.Candidate)
                           ? jMessage.GetNamedString(NegotiationAtributes.Candidate)
                           : null;

                    if (string.IsNullOrEmpty(sdpMid) || sdpMLineIndex == -1 || string.IsNullOrEmpty(sdpCandidate))
                    {
                        Debug.WriteLine($"[Error] Can't parse received message.\n{content}");
                        return;
                    }

                    var candidateInit           = new RTCIceCandidateInit();
                    candidateInit.Candidate     = sdpCandidate;
                    candidateInit.SdpMid        = sdpMid;
                    candidateInit.SdpMLineIndex = (ushort)sdpMLineIndex;
                    candidate = new RTCIceCandidate(candidateInit);

                    await PeerConnection.AddIceCandidate(candidate);

                    Debug.WriteLine($"Receiving ice candidate:\n{content}");
                }
            }).Wait();
        }
 public static SdpType ToNativePort(this RTCSdpType platformNative) => (SdpType)platformNative;
 public RTCSessionDescriptionInit(string sdp, RTCSdpType type)
 {
     HostObject = new JSObject();
     HostObject.SetObjectProperty("type", type.ToString().ToLower());
     HostObject.SetObjectProperty("sdp", sdp);
 }
 public static SdpType ToNet(this RTCSdpType self)
 {
     return((SdpType)self);
 }