private void Signaler_MessageFromPeer(object sender, Peer peer) { var message = peer.Message; if (message.Contains("OpenDataChannel")) { // A peer has let us know that they have begun initiating a data channel. In this scenario, // we are the "remote" peer so make sure _isInitiator is false. Begin gathering ice candidates. _isInitiator = false; RemotePeer = peer; OpenDataChannel(peer); // TODO: This is incorrect - message is definitely not the peer's name. return; } if (message.Contains("IceCandidate")) { var remoteCandidate = RTCIceCandidate.FromJsonString(message); _ice.AddRemoteCandidate(remoteCandidate); // TODO: Notify the ice transport when gathering is complete via the line below so it can change state. //_ice.AddRemoteCandidate(new RTCIceCandidateComplete()); return; } if (message.Contains("IceParameters")) { var iceParameters = RTCIceParameters.FromJsonString(message); // Start the ice transport with the appropriate role based on whether this is the initiator of the call. var role = _isInitiator ? RTCIceRole.Controlling : RTCIceRole.Controlled; _ice.Start(_gatherer, iceParameters, role); return; } if (message.Contains("DtlsParameters")) { var dtlsParameters = RTCDtlsParameters.FromJsonString(message); _dtls.Start(dtlsParameters); Debug.WriteLine("Dtls start called."); return; } // this order guarantees: if (message.Contains("SctpCapabilities")) { // Message ordering: alice -> bob; bob.start(); bob -> alice; alice.start(); alice -> datachannel -> bob var sctpCaps = RTCSctpCapabilities.FromJsonString(message); if (!_isInitiator) { Debug.WriteLine("Receiver: Waiting for OnDataChannel event and starting sctp."); // The remote side will receive notification when the data channel is opened. _sctp.OnDataChannel += Sctp_OnDataChannel; _sctp.OnStateChange += Sctp_OnStateChange; _sctp.Start(sctpCaps); var caps = RTCSctpTransport.GetCapabilities(); _signaler.SendToPeer(RemotePeer.Id, caps.ToJsonString()); } else { // The initiator has received sctp caps back from the remote peer, which means the remote peer // has already called sctp.start(). It's now safe to open a data channel, which will fire the // Sctp_OnDataChannel event on the remote side. Debug.WriteLine("Initiator: Creating the data channel and starting sctp."); _sctp.OnStateChange += Sctp_OnStateChange; _sctp.Start(sctpCaps); _dataChannel = new RTCDataChannel(_sctp, _dataChannelParams); _dataChannel.OnMessage += DataChannel_OnMessage; _dataChannel.OnError += DataChannel_OnError; _dataChannel.OnStateChange += DataChannel_OnStateChange; Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { IsSendEnabled = true; }); } } }
public void HandleMessageFromPeer(string message) { if (message.StartsWith("{\"candidate")) { Debug.WriteLine("contains IceCandidate (or IceCandidateComplete)"); Json jsonMessage = new Json(message); RTCIceGathererCandidate remoteCandidate = RTCIceGathererCandidate.Create(jsonMessage); _ice.AddRemoteCandidate(remoteCandidate); return; } if (message.StartsWith("{\"RTCIceParameters\":")) { Debug.WriteLine("contains IceParameters"); Json jsonMessage = new Json(message); RTCIceParameters iceParameters = new RTCIceParameters(jsonMessage); // Start the ice transport with the appropriate role based on whether this is the initiator of the call. var role = _isInitiator ? RTCIceRole.Controlling : RTCIceRole.Controlled; _ice.Start(_gatherer, iceParameters, role); return; } if (message.StartsWith("{\"RTCDtlsParameters\":")) { Debug.WriteLine("contains DtlsParameters"); Json jsonMessage = new Json(message); RTCDtlsParameters dtlsParameters = new RTCDtlsParameters(jsonMessage); _dtls.Start(dtlsParameters); Debug.WriteLine("Dtls start called."); return; } // this order guarantees: if (message.StartsWith("{\"RTCSctpCapabilities\":")) { Debug.WriteLine("contains SctpCapabilities"); Json jsonMessage = new Json(message); // Message ordering: alice -> bob; bob.start(); bob -> alice; alice.start(); alice -> datachannel -> bob RTCSctpCapabilities sctpCaps = new RTCSctpCapabilities(jsonMessage); if (!_isInitiator) { Debug.WriteLine("Receiver: Waiting for OnDataChannel event and starting sctp."); // The remote side will receive notification when the data channel is opened. _sctp.OnDataChannel += Sctp_OnDataChannel; _sctp.OnStateChange += Sctp_OnStateChange; _sctp.Start(sctpCaps); RTCSctpCapabilities caps = RTCSctpTransport.GetCapabilities(); OnSignalMessageToPeer(caps.ToJson().ToString()); } else { // The initiator has received sctp caps back from the remote peer, // which means the remote peer has already called sctp.start(). // It's now safe to open a data channel, which will fire the // Sctp_OnDataChannel event on the remote side. Debug.WriteLine("Initiator: Creating the data channel and starting sctp."); _sctp.OnStateChange += Sctp_OnStateChange; _sctp.Start(sctpCaps); RTCDataTransport data = RTCDataTransport.Cast(_sctp); _dataChannel = new RTCDataChannel(data, _dataChannelParams); _dataChannel.OnMessage += DataChannel_OnMessage; _dataChannel.OnError += DataChannel_OnError; _dataChannel.OnOpen += DataChannel_OnOpen; _dataChannel.OnClose += DataChannel_OnClose; } } }