public void OnMessageReceived(Action <dynamic>[] actions, string customer) { this.MessageReceived += (message, client) => { LastActiveTime = DateTime.Now; if (string.IsNullOrWhiteSpace(message)) { return; } if (message.Contains("keep") && message.Contains("alive")) { if (DateTime.Now > lastKeepaliveWriteTime.AddMinutes(15)) { LogUnit?.LogInformation($"Websocket Event: {message}"); lastKeepaliveWriteTime = DateTime.Now; } } else { LogUnit?.LogInformation($"Websocket Event: {message}"); } if (actions == null) { return; } foreach (var action in actions) { action?.Invoke(Newtonsoft.Json.JsonConvert.DeserializeObject <dynamic>(message)); } }; }
public async Task <string> OnFirstEvent(string customer, CancellationToken token) { waitFirstEvent = new EventWaitHandle(false, EventResetMode.ManualReset); this.MessageReceived += WebSocket_FirstEvent; if (await OpenWebSocket(token)) { if (waitFirstEvent.WaitOne(2000)) { LogUnit?.LogInformation($"Websocket Subscribe: {firstEvent}"); this.MessageReceived -= WebSocket_FirstEvent; return(firstEvent); } } throw new TimeoutException("WebSocket timed out after 2 seconds waiting for subscription event."); }
public async Task CreateWebSocket(string uri, string customer, TimeSpan expire, Action openAction = null, Action closeAction = null, Action <Exception> errorAction = null, Action renewAction = null, bool keepAliveEnabled = false, TimeSpan?keepAliveInterval = null, List <KeyValuePair <string, string> > header = null) { if (WebSocket?.State == System.Net.WebSockets.WebSocketState.Open) { return; } this.uri = new Uri(uri); await CloseWebSocket(CancellationToken.None); WebSocket = new ClientWebSocket(); if (header != null) { foreach (var h in header) { WebSocket.Options.SetRequestHeader(h.Key, h.Value); } } if (keepAliveEnabled && keepAliveInterval.HasValue) { WebSocket.Options.KeepAliveInterval = keepAliveInterval.Value; } //WebSocket.EnableAutoSendPing = keepAliveEnabled; //WebSocket.AutoSendPingInterval = (int)keepAliveInterval?.TotalSeconds; this.Opened = (client) => { if (client.WebSocket.State == System.Net.WebSockets.WebSocketState.Open) { LogUnit?.LogInformation($"Websocket Opened"); openAction?.Invoke(); Task.Factory.StartNew(async() => { bool done = false; while (!done) { await Task.Delay(expire, cancelSource.Token); if (cancelSource.IsCancellationRequested) { done = true; LogUnit?.LogInformation($"Websocket Expire - Cancelled"); } else if (IsWebSocketOpen) { if (keepAliveEnabled && client.LastActiveTime < DateTime.Now.Subtract(keepAliveInterval.Value.Add(keepAliveInterval.Value).Add(keepAliveInterval.Value))) { done = true; LogUnit?.LogInformation($"Websocket Expire - Closing"); await client?.CloseWebSocket(CancellationToken.None); } else { renewAction?.Invoke(); } } else { done = true; LogUnit?.LogInformation($"Websocket Expire - Not Open"); } } }, cancelSource.Token); StartListen(cancelSource.Token); } }; this.Closed = (client) => { cancelSource.Cancel(); LogUnit?.LogInformation($"Websocket Closed"); closeAction?.Invoke(); }; this.Error = (client, e) => { cancelSource.Cancel(); LogUnit?.LogError($"Websocket Error", e); errorAction?.Invoke(e); }; CancellationToken token = new CancellationToken(); await WebSocket.ConnectAsync(this.uri, token); this.Opened(this); OnOpen?.Invoke(this, null); }