private void HttpSignaler_MessageFromPeer(object sender, HttpSignalerMessageEvent e) { int peerId = int.Parse(e.Message.PeerId); string content = e.Message.Content; _call.MessageFromPeerTaskRun(peerId, content); }
private async void Signaler_MessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var complete = new ManualResetEvent(false); // Exactly like the case of Signaler_SignedIn, this event is fired // from the signaler task thread and like the other events, // the message must be processed on the GUI thread for concurrency // reasons. Unlike the connect / disconnect notifications these // events must be processed exactly one at a time and the next // message from the server should be held back until the current // message is fully processed. await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Do not invoke a .Wait() on the task result of // HandleMessageFromPeer! While this might seem as a // reasonable solution to processing the entire event from the // GUI thread before processing the next message in the GUI // thread queue, a .Wait() would also block any and all // events targeted toward the GUI thread. // // This would actually create a deadlock in some cases. All // events from ORTC are fired at the GUI thread queue and the // creation of a RTCCertificate requires an event notification // to indicate when the RTCCertificate awaited task is // complete. Because .Wait() would block the GUI thread the // notification that the RTCCertificate is completed would // never fire and the RTCCertificate generation task result // would never complete which the .Wait() is waiting upon // to complete. // // Bottom line, don't block the GUI thread using a .Wait() // on a task from the GUI thread - ever! HandleMessageFromPeer(sender, @event).ContinueWith((antecedent) => { Debug.WriteLine($"Message from peer handled: {@event.Message}"); complete.Set(); }); }); // By waiting on the async result the signaler's task is blocked // from processing the next signaler message until the current // message is fully processed. The signaler thread is allowed to // be blocked because events are never fired on the signaler's // tasks dispatchers. // // While .BeginInvoke() does ensure that each message is processed // by the GUI thread in the order the message is sent to the GUI // thread, it does not ensure the message is entirely processed // before the next message directed to the GUI thread is processed. // The moment an async/awaitable task happens on the GUI thread // the next message in the GUI queue is allowed to be processed. // Tasks and related methods cause the GUI thread to become // re-entrant to processing more messages whenever an async // related routine is called. complete.WaitOne(); }
private async Task HandleMessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var message = @event.Message; var peer = @event.Peer; if (message.StartsWith("OpenDataChannel", StringComparison.Ordinal)) { Debug.WriteLine("contains OpenDataChannel"); await SetupPeer(peer, false); } }
private async Task HandleMessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var message = @event.Message; var peer = @event.Peer; if (message.StartsWith("OpenDataChannel")) { Debug.WriteLine("contains OpenDataChannel"); await SetupPeer(peer, false); } _ortcController.HandleMessageFromPeer(message); }
private void Signaler_MessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var complete = new ManualResetEvent(false); // Exactly like the case of Signaler_SignedIn, this event is fired // from the signaler task thread and like the other events, // the message must be processed on the GUI thread for concurrency // reasons. Unlike the connect / disconnect notifications these // events must be processed exactly one at a time and the next // message from the server should be held back until the current // message is fully processed. this.BeginInvokeOnMainThread(() => { HandleMessageFromPeer(sender, @event).ContinueWith((antecedent) => { Debug.WriteLine("Message from peer handled: " + @event.Message); complete.Set(); }); }); }
private async Task HandleMessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var message = @event.Message; var peer = @event.Peer; if (message.StartsWith("OpenDataChannel")) { Debug.WriteLine("contains OpenDataChannel"); await SetupPeer(peer, false); } Tuple <OrtcController, ChatPage> tuple; if (!_chatSessions.TryGetValue(peer.Id, out tuple)) { Debug.WriteLine($"[WARNING] No peer found to direct remote message: {peer.Id} / {message}"); return; } tuple.Item1.HandleMessageFromPeer(message); }
private void Signaler_MessageFromPeer(object sender, HttpSignalerMessageEvent @event) { var complete = new ManualResetEvent(false); // Exactly like the case of Signaler_SignedIn, this event is fired // from the signaler task thread and like the other events, // the message must be processed on the GUI thread for concurrency // reasons. Unlike the connect / disconnect notifications these // events must be processed exactly one at a time and the next // message from the server should be held back until the current // message is fully processed. Device.BeginInvokeOnMainThread(() => { // Do not invoke a .Wait() on the task result of // HandleMessageFromPeer! While this might seem as a // reasonable solution to processing the entire event from the // GUI thread before processing the next message in the GUI // thread queue, a .Wait() would also block any and all // events targeted toward the GUI thread. // // This would actually create a deadlock in some cases. All // events from ORTC are fired at the GUI thread queue and the // creation of a RTCCertificate requires an event notification // to indicate when the RTCCertificate awaited task is // complete. Because .Wait() would block the GUI thread the // notification that the RTCCertificate is completed would // never fire and the RTCCertificate generation task result // would never complete which the .Wait() is waiting upon // to complete. // // Bottom line, don't block the GUI thread using a .Wait() // on a task from the GUI thread - ever! HandleMessageFromPeer(sender, @event).ContinueWith((antecedent) => { Debug.WriteLine($"Message from peer handled: {@event.Message}"); complete.Set(); }); }); }