private async void ReceiveAsync(CancellationToken token) { var buffer = new byte[1024 * 4]; var done = false; while (!done) { WebSocketReceiveResult result = null; try { result = await Socket.ReceiveAsync(new ArraySegment <byte>(buffer), token).ConfigureAwait(false); } catch (WebSocketException) { await StopAsync(graceful : false).ConfigureAwait(false); break; } catch (InvalidOperationException) { break; } catch (TaskCanceledException) { break; } catch (OperationCanceledException) { break; } MessageResponse message = null; // TODO: make serializers more modular switch (result?.MessageType) { case WebSocketMessageType.Text: var str = Encoding.UTF8.GetString(buffer, 0, result.Count); message = JsonConvert.DeserializeObject <MessageResponse>(str); break; case WebSocketMessageType.Close: await StopAsync(graceful : false).ConfigureAwait(false); done = true; break; case WebSocketMessageType.Binary: // TODO implement binary protocols break; case null: // do nothing; break; default: throw new ArgumentOutOfRangeException(); } if (message == null) { continue; } MessageReceived?.Invoke(this, new MessageEventArgs { Message = message }); if (message.Path != null && Watchers.ContainsKey(message.Path)) { lock (Watchers[message.Path]) { var removeThese = new List <int>(); var i = 0; foreach (var w in Watchers[message.Path]) { var wKeep = w.Invoke(message); if (wKeep != true) { removeThese.Add(i); } i++; } removeThese .Reverse(); // IMPORTANT: make sure you reverse so that the larger numbers get removed first, prevents wrong indexes later on. foreach (var r in removeThese) { Watchers[message.Path].RemoveAt(r); } } } if (message.Id == null) { continue; } Listeners.TryGetValue(message.Id, out var listener); if (listener == null) { continue; } var l = listener.Value; var keep = l.Callback(message); if (keep != true) { Listeners.TryRemove(message.Id, out var _); } l.TaskCompleter.SetResult(true); } }
protected Task SendMessageToAll(MessageResponse message, CancellationToken token) => Handler.SendMessageToAll(message, token);
protected Task SendMessage(WebSocker socket, MessageResponse message, CancellationToken token) => Handler.SendMessage(socket, message, token);
protected Task SendMessage(string socketId, MessageResponse message, CancellationToken token) => Handler.SendMessage(socketId, message, token);
protected Task ReplyMessage(MessageResponse message, CancellationToken token = default(CancellationToken)) => SendMessage(Socket, message, token);