private void HandlePatch(ServerEvent serverEvent) { lock (CacheLock) { var dest = Cache.SelectToken(serverEvent.Path); if (dest == null) { dest = new JObject(); Cache[serverEvent.Path] = dest; } foreach (var key in serverEvent.Data) { if (key.First.ToObject <object>() != null) { dest[key.Path] = key.First; } else { (dest as JObject).Remove(key.Path); } } ValueChanged?.Invoke(Cache); } }
private async Task ListenToServerEvents() { UrlBuilder.AppendToPath(Endpoints.Json); while (!CancellationToken.IsCancellationRequested) { var urlBuilderCopy = UrlBuilder.Copy(); urlBuilderCopy.AddParam(Params.Auth, await IdTokenFactory()); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(urlBuilderCopy.Url)); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream")); HttpResponseMessage response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); using (Stream stream = await response.Content.ReadAsStreamAsync()) using (StreamReader reader = new StreamReader(stream)) { while (!CancellationToken.IsCancellationRequested) { var serializedEventType = await reader.ReadLineAsync(); if (String.IsNullOrWhiteSpace(serializedEventType)) { continue; } string serializedData = await reader.ReadLineAsync(); ServerEvent serverEvent = ServerEvent.Parse(serializedEventType, serializedData); if (serverEvent.Type == ServerEventType.AuthRevoked) { break; } if (serverEvent.Type == ServerEventType.KeepAlive) { continue; } if (serverEvent.Type == ServerEventType.Cancel) { throw new PremissionDeniedException(); } if (serverEvent.Type == ServerEventType.Put) { HandlePut(serverEvent); } else if (serverEvent.Type == ServerEventType.Patch) { HandlePatch(serverEvent); } } } } // We clear all the events ValueChanged = ChildAdded = ChildChanged = ChildRemoved = null; }
private void HandlePut(ServerEvent serverEvent) { lock (CacheLock) { var token = Cache.SelectToken(serverEvent.ChildKey, false); if (token != null && token.Parent == null) { var newChildren = serverEvent.Data.Children().Except(Cache.Children()); foreach (var child in newChildren) { ChildAdded?.Invoke(child.GetType() == typeof(JValue) ? child : child.First); } var removedChildren = Cache.Children().Except(serverEvent.Data.Children()); foreach (var child in removedChildren) { ChildRemoved?.Invoke(child.First); } Cache = serverEvent.Data as JObject ?? new JObject(); } else { if (token == null) { Cache[serverEvent.Path] = serverEvent.Data as JToken; ChildAdded?.Invoke(Cache[serverEvent.Path]); } else { if (serverEvent.Data.ToObject <object>() == null) { var removedChild = Cache.SelectToken(serverEvent.Path, false); Cache.SelectToken(serverEvent.Path, false)?.Parent?.Remove(); ChildRemoved?.Invoke(removedChild); } else { var subChildPath = string.Join(".", serverEvent.Path.Split('.').Skip(1)); token[subChildPath] = serverEvent.Data as JToken; ChildChanged?.Invoke(Cache.SelectToken(serverEvent.ChildKey, false)); } } } ValueChanged?.Invoke(Cache); } }