internal void DispatchEvent(ServerSentEvent @event) { Action <ServerSentEvent> action = DispatchEventAsync; new Task(() => { DispatchEventAsync(@event); }, this.stopToken).Start(); }
private void DispatchEventAsync(ServerSentEvent @event) { Tuple <object, Type, MethodInfo> target = null; // See if we have a listener for our event type if (string.IsNullOrEmpty(@event.EventType) || !actions.TryGetValue(@event.EventType, out target)) { if (defaultListener != null) { defaultListener(@event); } return; } // Get the type Type T = target.Item2; MethodInfo method = target.Item3; try { MethodInfo createObject = typeof(JsonSerializer) .GetMethod("DeserializeFromString", new Type[] { typeof(System.String) }); MethodInfo createGenericObject = createObject.MakeGenericMethod(T); object obj = createGenericObject.Invoke(null, new object[] { @event.Data }); method.Invoke(target.Item1, new object[] { @event, obj }); } catch (Exception ex) { // Couldn't cast or dispatch our event to the listener. Go to the default listener if (defaultListener != null) { defaultListener(@event); } } }
public override Task <ConnectionState> Run(Action <ServerSentEvent> MsgReceivedCallback, CancellationToken cancelToken) { Task <ConnectionState> task = new Task <ConnectionState>(() => { var stream = response.GetResponseStream(); byte[] buffer = new byte[1024 * 8]; var taskRead = stream.ReadAsync(buffer, 0, buffer.Length, cancelToken); try { taskRead.Wait(cancelToken); } catch (Exception ex) { // how to handle exceptions? } if (cancelToken.IsCancellationRequested || !taskRead.IsCompleted) { this.Client.isReconnecting = true; return(new ClosedState(this.Client)); } int bytesRead = taskRead.Result; string text = Encoding.UTF8.GetString(buffer, 0, bytesRead); text = remainingText + text; string[] lines = SplitIntoLines(text, out remainingText); //string[] lines = reEvent.Split(text); foreach (string line in lines) { if (cancelToken.IsCancellationRequested) { break; } // blank line => dispatch event if (string.IsNullOrEmpty(line.Trim()) && serverEvent != null) { this.Client.DispatchEvent(serverEvent); serverEvent = null; } // Begins with ":" => ignore (comment) else if (line.StartsWith(":")) { } // Anything else else { string fieldName = String.Empty; string fieldValue = String.Empty; if (line.Contains(':')) { int index = line.IndexOf(':'); fieldName = line.Substring(0, index); fieldValue = line.Substring(index + 1).TrimStart(); } else { fieldName = line; } serverEvent = serverEvent ?? new ServerSentEvent(); switch (fieldName.ToLower()) { case "event": serverEvent.EventType = fieldValue; break; case "data": serverEvent.Data = fieldValue + "\n"; break; case "id": serverEvent.LastEventId = fieldValue; break; case "retry": int retry = 0; if (Int32.TryParse(fieldValue, out retry)) { serverEvent.Retry = retry; } break; default: // Invalid break; } } } // If no cancel requested, keep going if (!cancelToken.IsCancellationRequested) { return(this); } // Else we disconnect this.Client.isReconnecting = true; return(new ClosedState(this.Client)); } ); task.Start(); return(task); }