public async Task SubscribeChildrenChangeTest() { var path = $"/{DateTime.Now:yyyy_MM_dd_HH_mm_ss_ff}"; var path2 = $"{path}/123"; try { if (await _client.ExistsAsync(path)) { await _client.DeleteRecursiveAsync(path); } var types = new List <Watcher.Event.EventType>(); var semaphore = new Semaphore(0, 2); await _client.SubscribeDataChange(path, (client, args) => { if (args.Type == Watcher.Event.EventType.NodeCreated) { semaphore.Release(); } return(Task.CompletedTask); }); await _client.SubscribeChildrenChange(path, (client, args) => { types.Add(args.Type); semaphore.Release(); return(Task.CompletedTask); }); await _client.CreatePersistentAsync(path, null); semaphore.WaitOne(10000); await _client.CreatePersistentAsync(path2, null); semaphore.WaitOne(10000); Assert.Equal(Watcher.Event.EventType.NodeChildrenChanged, types[0]); } finally { if (await _client.ExistsAsync(path)) { await _client.DeleteRecursiveAsync(path); } } }
public async Task SubscribeDataChangeTest() { var path = $"/{DateTime.Now:yyyy_MM_dd_HH_mm_ss_ff}"; try { if (await _client.ExistsAsync(path)) { await _client.DeleteAsync(path); } var types = new List <Watcher.Event.EventType>(); var waitEvent = new AutoResetEvent(false); await _client.SubscribeDataChange(path, (client, args) => { types.Add(args.Type); waitEvent.Set(); return(Task.CompletedTask); }); //created await _client.CreateEphemeralAsync(path, null); waitEvent.WaitOne(10000); //Assert.Equal(Watcher.Event.EventType.NodeCreated, types[0]); //modify await _client.SetDataAsync(path, new byte[] { 1 }); waitEvent.WaitOne(10000); // Assert.Equal(Watcher.Event.EventType.NodeDataChanged, types[1]); //deleted await _client.DeleteAsync(path); waitEvent.WaitOne(10000); // Assert.Equal(Watcher.Event.EventType.NodeDeleted, types[2]); } finally { if (await _client.ExistsAsync(path)) { await _client.DeleteAsync(path); } } }
public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken)) { var existPath = await _client.ExistsAsync(ListenerPath); if (!existPath) { await _client.CreateRecursiveAsync(ListenerPath, Encoding.UTF8.GetBytes("Bucket.Listener")); } await _client.SubscribeDataChange(ListenerPath, async (ct, args) => { if (!_isSubscribe) { return; } var currentData = Encoding.UTF8.GetString(args.CurrentData.ToArray()); if (!string.IsNullOrWhiteSpace(currentData)) { var command = JsonConvert.DeserializeObject <Values.NetworkCommand>(currentData); if (args.Path.ToLower() == ListenerPath.ToLower()) { switch (args.Type) { case Watcher.Event.EventType.NodeDataChanged: await _extractCommand.ExtractCommandMessage(command); break; } } } }); _isSubscribe = true; }
/// <summary> /// 监听指定的节点 /// </summary> /// <param name="node">节点名称</param> /// <param name="callback">节点数据更改或者节点被删除时会触发该事件</param> /// <returns>Task</returns> public Task Listen(string node, CacheCallback <string> callback) { NodeDataChangeHandler handler = null; handler = (ct, args) => { //节点被删除或者节点数据改动时清理该节点对应的缓存数据 if (args.Type == Watcher.Event.EventType.NodeDataChanged || args.Type == Watcher.Event.EventType.NodeDeleted) { if (callback != null) { callback(args.Path); } } return(Task.CompletedTask); }; NodeDataChangeHandler handlerLast = null; if (_handlerRecord.ContainsKey(node)) { handlerLast = _handlerRecord[node]; } if (handlerLast != null) { //取消侦听 _zkClient.UnSubscribeDataChange(node, handlerLast); } _handlerRecord[node] = handler; Task task = _zkClient.SubscribeDataChange(node, handler); return(task); }
private async Task <bool> SetRouteAsync(ServiceRouteDescriptor route, IZookeeperClient zooKeeperClient) { try { bool isSetRoute = false; _logger.LogDebug($"准备添加{route.ServiceDescriptor.Id}服务路由。"); var zooKeeperClients = await _zookeeperClientProvider.GetZooKeeperClients(); await CreateSubdirectory(zooKeeperClient, _configInfo.RoutePath); var path = _configInfo.RoutePath; if (!path.EndsWith("/")) { path += "/"; } var nodePath = $"{path}{route.ServiceDescriptor.Id}"; var nodeData = _serializer.Serialize(route); _logger.LogDebug($"服务路由内容为:{Encoding.UTF8.GetString(nodeData)}。"); if (!nodeWatchers.ContainsKey(nodePath)) { var watcher = nodeWatchers.GetOrAdd(nodePath, f => new NodeMonitorWatcher(path, async(oldData, newData) => await NodeChange(oldData, newData))); await zooKeeperClient.SubscribeDataChange(nodePath, watcher.HandleNodeDataChange); } if (!await zooKeeperClient.ExistsAsync(nodePath)) { _logger.LogDebug($"节点:{nodePath}不存在将进行创建。"); await zooKeeperClient.CreateAsync(nodePath, nodeData, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } else { var onlineData = (await zooKeeperClient.GetDataAsync(nodePath)).ToArray(); if (!DataEquals(nodeData, onlineData)) { await zooKeeperClient.SetDataAsync(nodePath, nodeData); _logger.LogDebug($"{nodePath}节点的缓存的服务路由与服务注册中心不一致,路由数据已被更新。"); isSetRoute = true; } } return(isSetRoute); } catch (Exception ex) { _logger.LogError($"{route.ServiceDescriptor.Id}服务的路由注册失败,原因:{ex.Message}"); return(false); } }
public async Task SubscribeDataChange(string key, Action <NodeDataChangeArgs> action) { var keys = Data.Keys.Where(x => x.StartsWith(key, StringComparison.InvariantCultureIgnoreCase)); foreach (var k in keys) { var path = $"/{k.Replace(":", "/")}"; await _client.SubscribeDataChange(path, (client, args) => { if (args.Type != Watcher.Event.EventType.NodeDeleted) { Data[k] = Encoding.UTF8.GetString(args.CurrentData.ToArray()); } else { Data.Remove(k); } action.Invoke(args); return(Task.CompletedTask); }); } }
/// <summary> /// 订阅节点数据变更 /// </summary> /// <param name="path">节点路径</param> /// <param name="listener">监听者</param> public void SubscribeDataChange(string path, NodeDataChangeHandler listener) { client.SubscribeDataChange(path, listener); }