Exemple #1
0
        public async Task <IActionResult> Client_Offline(string address, string clientId)
        {
            if (Appsettings.IsPreviewMode)
            {
                return(Json(new
                {
                    success = false,
                    message = "演示模式请勿断开客户端"
                }));
            }

            var action = new WebsocketAction {
                Action = "offline"
            };
            var result = await _remoteServerNodeProxy.OneClientDoActionAsync(address, clientId, action);

            if (result)
            {
                dynamic param = new ExpandoObject();
                param.clientId = clientId;
                param.userName = this.GetCurrentUserName();
                TinyEventBus.Instance.Fire(EventKeys.DISCONNECT_CLIENT_SUCCESS, param);
            }

            _logger.LogInformation("Request remote node {0} 's action OneClientDoAction {1} .", address, result ? "success" : "fail");

            return(Json(new
            {
                success = true,
            }));
        }
 public void SendActionToAppClients(string appId, WebsocketAction action)
 {
     lock (_lockObj)
     {
         if (Clients.Count == 0)
         {
             return;
         }
         var appClients = Clients.Where(c => c.AppId == appId);
         if (appClients.Count() == 0)
         {
             return;
         }
         var json = JsonConvert.SerializeObject(action);
         var data = Encoding.UTF8.GetBytes(json);
         foreach (var webSocket in appClients)
         {
             if (webSocket.AppId == appId && webSocket.Client.State == WebSocketState.Open)
             {
                 webSocket.Client.SendAsync(new ArraySegment <byte>(data, 0, data.Length), WebSocketMessageType.Text, true,
                                            CancellationToken.None);
             }
         }
     }
 }
Exemple #3
0
        /// <summary>
        /// 上线多个配置
        /// </summary>
        /// <param name="configIds"></param>
        /// <returns></returns>
        public async Task <IActionResult> OfflineSome([FromBody] List <string> configIds)
        {
            if (configIds == null)
            {
                throw new ArgumentNullException("configIds");
            }

            var nodes = await _serverNodeService.GetAllNodesAsync();

            foreach (var configId in configIds)
            {
                var config = await _configService.GetAsync(configId);

                if (config == null)
                {
                    return(Json(new
                    {
                        success = false,
                        message = "未找到对应的配置项。"
                    }));
                }
                if (config.OnlineStatus == OnlineStatus.WaitPublish)
                {
                    continue;
                }
                config.OnlineStatus = OnlineStatus.WaitPublish;
                var result = await _configService.UpdateAsync(config);

                if (result)
                {
                    await _sysLogService.AddSysLogAsync(new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"下线配置【Key:{config.Key}】 【Group:{config.Group}】 【AppId:{config.AppId}】"
                    });

                    //notice clients the config item is offline
                    var action = new WebsocketAction {
                        Action = ActionConst.Remove, Item = new ConfigItem {
                            group = config.Group, key = config.Key, value = config.Value
                        }
                    };
                    foreach (var node in nodes)
                    {
                        if (node.Status == NodeStatus.Offline)
                        {
                            continue;
                        }
                        await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                    }
                }
            }
            return(Json(new
            {
                success = true,
                message = "下线配置成功"
            }));
        }
Exemple #4
0
        public async Task <bool> AllClientsDoActionAsync(string address, WebsocketAction action)
        {
            var result = await FunctionUtil.TRY(async() =>
            {
                using (var resp = await(address + "/RemoteOP/AllClientsDoAction")
                                  .AsHttp("POST", action)
                                  .Config(new RequestOptions {
                    ContentType = "application/json"
                })
                                  .SendAsync())
                {
                    if (resp.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        var result = resp.Deserialize <dynamic>();

                        if ((bool)result.success)
                        {
                            return(true);
                        }
                    }

                    return(false);
                }
            }, 5);

            await _sysLogService.AddSysLogAsync(new SysLog
            {
                LogTime = DateTime.Now,
                LogType = result ? SysLogType.Normal : SysLogType.Warn,
                LogText = $"通知节点{address}所有客户端:{action.Action} 响应:{(result ? "成功" : "失败")}"
            });

            return(result);
        }
        private async Task<WebsocketAction> CreateRemoveWebsocketAction(Config oldConfig, string appId)
        {
            //获取app此时的配置列表合并继承的app配置 字典
            var configs = await _configService.GetPublishedConfigsByAppIdWithInheritanced_Dictionary(appId);
            var oldKey = _configService.GenerateKey(oldConfig);
            //如果oldkey已经不存在,返回remove的action
            if (!configs.ContainsKey(oldKey))
            {
                var action = new WebsocketAction { Action = ActionConst.Remove, Item = new ConfigItem { group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value } };
                return action;
            }
            else
            {
                //如果还在,那么说明有继承的app的配置项目的key跟oldkey一样,那么使用继承的配置的值
                //返回update的action
                var config = configs[oldKey];
                var action = new WebsocketAction
                {
                    Action = ActionConst.Update,
                    Item = new ConfigItem { group = config.Group, key = config.Key, value = config.Value },
                    OldItem = new ConfigItem { group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value }
                };

                return action;
            }
        }
        public async Task<IActionResult> Publish(string configId)
        {
            if (string.IsNullOrEmpty(configId))
            {
                throw new ArgumentNullException("configId");
            }

            var config = await _configService.GetAsync(configId);
            if (config == null)
            {
                return Json(new
                {
                    success = false,
                    message = "未找到对应的配置项。"
                });
            }

            if (config.OnlineStatus == OnlineStatus.Online)
            {
                return Json(new
                {
                    success = false,
                    message = "该配置已上线"
                });
            }

            config.OnlineStatus = OnlineStatus.Online;
            var result = await _configService.UpdateAsync(config);
            if (result)
            {
                await _sysLogService.AddSysLogAsync(new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    AppId = config.AppId,
                    LogText = $"上线配置【Key:{config.Key}】 【Group:{config.Group}】 【AppId:{config.AppId}】"
                });
                //notice clients config item is published
                var action = new WebsocketAction
                {
                    Action = ActionConst.Add,
                    Item = new ConfigItem { group = config.Group, key = config.Key, value = config.Value }
                };
                var nodes = await _serverNodeService.GetAllNodesAsync();
                foreach (var node in nodes)
                {
                    if (node.Status == NodeStatus.Offline)
                    {
                        continue;
                    }
                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                }
            }
            return Json(new
            {
                success = result,
                message = !result ? "上线配置失败,请查看错误日志" : ""
            });
        }
Exemple #7
0
        public async Task <IActionResult> Delete(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException("id");
            }

            var config = await _configService.GetAsync(id);

            if (config == null)
            {
                return(Json(new
                {
                    success = false,
                    message = "未找到对应的配置项。"
                }));
            }

            config.Status = ConfigStatus.Deleted;

            var result = await _configService.UpdateAsync(config);

            if (result)
            {
                //add syslog
                await _sysLogService.AddSysLogSync(new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    AppId   = config.AppId,
                    LogText = $"删除配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                });

                //notice clients
                var action = new WebsocketAction {
                    Action = ActionConst.Remove, Item = new ConfigItem {
                        group = config.Group, key = config.Key, value = config.Value
                    }
                };
                var nodes = await _serverNodeService.GetAllNodesAsync();

                foreach (var node in nodes)
                {
                    if (node.Status == NodeStatus.Offline)
                    {
                        continue;
                    }
                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                }
            }

            return(Json(new
            {
                success = result,
                message = !result ? "修改配置失败,请查看错误日志" : ""
            }));
        }
 public async Task SendActionToOne(WebsocketClient client, WebsocketAction action)
 {
     if (client.Client.State == WebSocketState.Open)
     {
         var json = JsonConvert.SerializeObject(action);
         var data = Encoding.UTF8.GetBytes(json);
         await client.Client.SendAsync(new ArraySegment <byte>(data, 0, data.Length), WebSocketMessageType.Text, true,
                                       CancellationToken.None);
     }
 }
Exemple #9
0
        public async Task <IActionResult> Client_Reload(string address, string clientId)
        {
            var action = new WebsocketAction {
                Action = "reload"
            };
            var result = await _remoteServerNodeProxy.OneClientDoActionAsync(address, clientId, action);

            _logger.LogInformation("Request remote node {0} 's action OneClientDoAction {1} .", address, result ? "success" : "fail");

            return(Json(new
            {
                success = true,
            }));
        }
Exemple #10
0
        public IActionResult AllClientsDoActionAsync([FromBody] WebsocketAction action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            WebsocketCollection.Instance.SendActionToAll(action);

            return(Json(new
            {
                success = true,
            }));
        }
Exemple #11
0
        public async Task <IActionResult> AllClients_Reload(string address)
        {
            var action = new WebsocketAction {
                Action = "reload"
            };
            var nodes = await _serverNodeService.GetAllNodesAsync();

            var result = await _remoteServerNodeProxy.AllClientsDoActionAsync(address, action);

            _logger.LogInformation("Request remote node {0} 's action AllClientsDoAction {1} .", address, result ? "success" : "fail");

            return(Json(new
            {
                success = true,
            }));
        }
Exemple #12
0
        public IActionResult AppClientsDoActionAsync([FromQuery] string appId, [FromBody] WebsocketAction action)
        {
            if (string.IsNullOrEmpty(appId))
            {
                throw new ArgumentNullException(nameof(appId));
            }
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            WebsocketCollection.Instance.SendActionToAppClients(appId, action);

            return(Json(new
            {
                success = true,
            }));
        }
        public void SendActionToAll(WebsocketAction action)
        {
            if (_Clients.Count == 0)
            {
                return;
            }

            var json = JsonConvert.SerializeObject(action);
            var data = Encoding.UTF8.GetBytes(json);

            foreach (var webSocket in _Clients)
            {
                if (webSocket.Value.Client.State == WebSocketState.Open)
                {
                    webSocket.Value.Client.SendAsync(new ArraySegment <byte>(data, 0, data.Length), WebSocketMessageType.Text, true,
                                                     CancellationToken.None);
                }
            }
        }
Exemple #14
0
        public IActionResult OneClientDoActionAsync([FromQuery] string clientId, [FromBody] WebsocketAction action)
        {
            var client = WebsocketCollection.Instance.Get(clientId);

            if (client == null)
            {
                throw new Exception($"Can not find websocket client by id: {clientId}");
            }
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            WebsocketCollection.Instance.SendActionToOne(client, action);

            return(Json(new
            {
                success = true,
            }));
        }
        public async Task <IActionResult> Client_Offline(string address, string clientId)
        {
            if (Appsettings.IsPreviewMode)
            {
                return(Json(new
                {
                    success = false,
                    message = "演示模式请勿断开客户端"
                }));
            }

            var action = new WebsocketAction {
                Action = "offline"
            };
            var result = await _remoteServerNodeProxy.OneClientDoActionAsync(address, clientId, action);

            _logger.LogInformation("Request remote node {0} 's action OneClientDoAction {1} .", address, result ? "success" : "fail");

            return(Json(new
            {
                success = true,
            }));
        }
Exemple #16
0
        public async Task <bool> OneClientDoActionAsync(string address, string clientId, WebsocketAction action)
        {
            var result = await FunctionUtil.TRY(async() =>
            {
                using (var resp = await(address + "/RemoteOP/OneClientDoAction?clientId=" + clientId)
                                  .AsHttp("POST", action)
                                  .Config(new RequestOptions {
                    ContentType = "application/json"
                })
                                  .SendAsync())
                {
                    if (resp.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        var result = resp.Deserialize <dynamic>();

                        if ((bool)result.success)
                        {
                            if (action.Action == ActionConst.Offline || action.Action == ActionConst.Remove)
                            {
                                if (_serverNodeClientReports.ContainsKey(address))
                                {
                                    if (_serverNodeClientReports[address].Infos != null)
                                    {
                                        var report = _serverNodeClientReports[address];
                                        report.Infos.RemoveAll(c => c.Id == clientId);
                                        report.ClientCount = report.Infos.Count;
                                    }
                                }
                            }

                            return(true);
                        }
                    }

                    return(false);
                }
            }, 5);

            using (var service = GetSysLogService())
            {
                await service.AddSysLogAsync(new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = result ? SysLogType.Normal : SysLogType.Warn,
                    LogText = $"通知节点【{address}】的客户端【{clientId}】:【{action.Action}】 响应:{(result ? "成功" : "失败")}"
                });
            }

            return(result);
        }
Exemple #17
0
        public async Task <IActionResult> Rollback(string configId, string logId)
        {
            if (string.IsNullOrEmpty(configId))
            {
                throw new ArgumentNullException("configId");
            }
            if (string.IsNullOrEmpty(logId))
            {
                throw new ArgumentNullException("logId");
            }

            var config = await _configService.GetAsync(configId);

            if (config == null)
            {
                return(Json(new
                {
                    success = false,
                    message = "未找到对应的配置项。"
                }));
            }
            var oldConfig = new Config
            {
                Key   = config.Key,
                Group = config.Group,
                Value = config.Value
            };

            var log = await _modifyLogService.GetAsync(logId);

            if (config == null)
            {
                return(Json(new
                {
                    success = false,
                    message = "未找到对应的配置项的历史记录项。"
                }));
            }
            config.Key        = log.Key;
            config.Group      = log.Group;
            config.Value      = log.Value;
            config.UpdateTime = DateTime.Now;

            var result = await _configService.UpdateAsync(config);

            if (result)
            {
                //add modify log
                await _modifyLogService.AddAsync(new ModifyLog
                {
                    Id         = Guid.NewGuid().ToString("N"),
                    ConfigId   = config.Id,
                    Key        = config.Key,
                    Group      = config.Group,
                    Value      = config.Value,
                    ModifyTime = config.UpdateTime.Value
                });

                //add syslog
                await _sysLogService.AddSysLogSync(new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    AppId   = config.AppId,
                    LogText = $"回滚配置【Key:{config.Key}】 【Group:{config.Group}】 【AppId:{config.AppId}】至历史记录:{logId}"
                });

                //notice clients
                var action = new WebsocketAction
                {
                    Action = ActionConst.Update,
                    Item   = new ConfigItem {
                        group = config.Group, key = config.Key, value = config.Value
                    },
                    OldItem = new ConfigItem {
                        group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                    }
                };
                var nodes = await _serverNodeService.GetAllNodesAsync();

                foreach (var node in nodes)
                {
                    if (node.Status == NodeStatus.Offline)
                    {
                        continue;
                    }
                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                }
            }

            return(Json(new
            {
                success = result,
                message = !result ? "回滚失败,请查看错误日志。" : ""
            }));
        }
Exemple #18
0
        private void RegisterWebsocketAction()
        {
            TinyEventBus.Instance.Regist(EventKeys.EDIT_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;

                if (config != null)
                {
                    if (config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Update,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            },
                            OldItem = new ConfigItem {
                                group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                            }
                        };
                        using (var serverNodeService = GetServerNodeService())
                        {
                            var nodes      = await serverNodeService.GetAllNodesAsync();
                            var noticeApps = await GetNeedNoticeInheritancedFromAppsAction(config);
                            noticeApps.Add(config.AppId, action);

                            foreach (var node in nodes)
                            {
                                if (node.Status == NodeStatus.Offline)
                                {
                                    continue;
                                }
                                foreach (var kv in noticeApps)
                                {
                                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, kv.Key, kv.Value);
                                }
                            }
                        }
                    }
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.DELETE_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;
                if (config != null)
                {
                    var action = await CreateRemoveWebsocketAction(config, config.AppId);
                    using (var serverNodeService = GetServerNodeService())
                    {
                        var nodes      = await serverNodeService.GetAllNodesAsync();
                        var noticeApps = await GetNeedNoticeInheritancedFromAppsAction(config);
                        noticeApps.Add(config.AppId, await CreateRemoveWebsocketAction(oldConfig, config.AppId));

                        foreach (var node in nodes)
                        {
                            if (node.Status == NodeStatus.Offline)
                            {
                                continue;
                            }
                            foreach (var kv in noticeApps)
                            {
                                await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, kv.Key, kv.Value);
                            }
                        }
                    }
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.OFFLINE_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;
                if (config != null)
                {
                    //notice clients the config item is offline
                    using (var serverNodeService = GetServerNodeService())
                    {
                        var nodes      = await serverNodeService.GetAllNodesAsync();
                        var noticeApps = await GetNeedNoticeInheritancedFromAppsAction(config);
                        noticeApps.Add(config.AppId, await CreateRemoveWebsocketAction(oldConfig, config.AppId));

                        foreach (var node in nodes)
                        {
                            if (node.Status == NodeStatus.Offline)
                            {
                                continue;
                            }
                            foreach (var kv in noticeApps)
                            {
                                await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, kv.Key, kv.Value);
                            }
                        }
                    }
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.PUBLISH_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;

                if (config != null)
                {
                    if (config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients config item is published
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Add,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            }
                        };
                        using (var serverNodeService = GetServerNodeService())
                        {
                            var nodes      = await serverNodeService.GetAllNodesAsync();
                            var noticeApps = await GetNeedNoticeInheritancedFromAppsAction(config);
                            noticeApps.Add(config.AppId, action);

                            foreach (var node in nodes)
                            {
                                if (node.Status == NodeStatus.Offline)
                                {
                                    continue;
                                }
                                foreach (var item in noticeApps)
                                {
                                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, item.Key, item.Value);
                                }
                            }
                        }
                    }
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.ROLLBACK_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;

                ModifyLog modifyLog = param_dy.modifyLog;

                if (config != null && oldConfig != null)
                {
                    if (config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Update,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            },
                            OldItem = new ConfigItem {
                                group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                            }
                        };
                        using (var serverNodeService = GetServerNodeService())
                        {
                            var nodes      = await serverNodeService.GetAllNodesAsync();
                            var noticeApps = await GetNeedNoticeInheritancedFromAppsAction(config);
                            noticeApps.Add(config.AppId, action);

                            foreach (var node in nodes)
                            {
                                if (node.Status == NodeStatus.Offline)
                                {
                                    continue;
                                }
                                foreach (var item in noticeApps)
                                {
                                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, item.Key, item.Value);
                                }
                            }
                        }
                    }
                }
            });
        }
Exemple #19
0
        public async Task <IActionResult> Edit([FromBody] ConfigVM model)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }

            var config = await _configService.GetAsync(model.Id);

            if (config == null)
            {
                return(Json(new
                {
                    success = false,
                    message = "未找到对应的配置项。"
                }));
            }
            var oldConfig = new Config
            {
                Key   = config.Key,
                Group = config.Group,
                Value = config.Value
            };

            if (config.Group != model.Group || config.Key != model.Key)
            {
                var anotherConfig = await _configService.GetByAppIdKey(model.AppId, model.Group, model.Key);

                if (anotherConfig != null)
                {
                    return(Json(new
                    {
                        success = false,
                        message = "配置键已存在,请重新输入。"
                    }));
                }
            }

            config.AppId       = model.AppId;
            config.Description = model.Description;
            config.Key         = model.Key;
            config.Value       = model.Value;
            config.Group       = model.Group;
            config.Status      = model.Status;
            config.UpdateTime  = DateTime.Now;

            var result = await _configService.UpdateAsync(config);

            if (result && !IsOnlyUpdateDescription(config, oldConfig))
            {
                //add modify log
                await _modifyLogService.AddAsync(new ModifyLog
                {
                    Id         = Guid.NewGuid().ToString("N"),
                    ConfigId   = config.Id,
                    Key        = config.Key,
                    Group      = config.Group,
                    Value      = config.Value,
                    ModifyTime = config.UpdateTime.Value
                });

                //syslog
                await _sysLogService.AddSysLogSync(new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    AppId   = config.AppId,
                    LogText = $"编辑配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                });

                //notice clients
                var action = new WebsocketAction
                {
                    Action = ActionConst.Update,
                    Item   = new ConfigItem {
                        group = config.Group, key = config.Key, value = config.Value
                    },
                    OldItem = new ConfigItem {
                        group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                    }
                };
                var nodes = await _serverNodeService.GetAllNodesAsync();

                foreach (var node in nodes)
                {
                    if (node.Status == NodeStatus.Offline)
                    {
                        continue;
                    }
                    await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                }
            }

            return(Json(new
            {
                success = result,
                message = !result ? "修改配置失败,请查看错误日志。" : ""
            }));
        }
Exemple #20
0
        /// <summary>
        /// 注册添加系统日志事件
        /// </summary>
        private void RegisterAddSysLog()
        {
            TinyEventBus.Instance.Regist(EventKeys.ADMIN_LOGIN_SUCCESS, (parm) =>
            {
                var log = new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    LogText = $"管理员登录成功"
                };
                _sysLogService.AddSysLogAsync(log);
            });

            TinyEventBus.Instance.Regist(EventKeys.INIT_ADMIN_PASSWORD_SUCCESS, (parm) =>
            {
                var log = new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    LogText = $"管理员密码初始化成功"
                };
                _sysLogService.AddSysLogAsync(log);
            });

            TinyEventBus.Instance.Regist(EventKeys.RESET_ADMIN_PASSWORD_SUCCESS, (parm) =>
            {
                var log = new SysLog
                {
                    LogTime = DateTime.Now,
                    LogType = SysLogType.Normal,
                    LogText = $"修改管理员密码成功"
                };
                _sysLogService.AddSysLogAsync(log);
            });

            TinyEventBus.Instance.Regist(EventKeys.ADD_APP_SUCCESS, (param) =>
            {
                var app = param as App;
                if (app != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        LogText = $"新增应用【AppId:{app.Id}】【AppName:{app.Name}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });

            // app
            TinyEventBus.Instance.Regist(EventKeys.EDIT_APP_SUCCESS, (param) =>
            {
                var app = param as App;
                if (app != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        LogText = $"编辑应用【AppId:{app.Id}】【AppName:{app.Name}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.DISABLE_OR_ENABLE_APP_SUCCESS, (param) =>
            {
                var app = param as App;
                if (app != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        LogText = $"{(app.Enabled ? "启用" : "禁用")}应用【AppId:{app.Id}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.DELETE_APP_SUCCESS, (param) =>
            {
                var app = param as App;
                if (app != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        LogText = $"删除应用【AppId:{app.Id}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.DELETE_APP_SUCCESS, (param) =>
            {
                var app = param as App;
                if (app != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        LogText = $"删除应用【AppId:{app.Id}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });
            //config
            TinyEventBus.Instance.Regist(EventKeys.ADD_CONFIG_SUCCESS, (param) =>
            {
                var config = param as Config;
                if (config != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"新增配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                    };
                    _sysLogService.AddSysLogAsync(log);

                    _modifyLogService.AddAsync(new ModifyLog
                    {
                        Id         = Guid.NewGuid().ToString("N"),
                        ConfigId   = config.Id,
                        Key        = config.Key,
                        Group      = config.Group,
                        Value      = config.Value,
                        ModifyTime = config.CreateTime
                    });
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.EDIT_CONFIG_SUCCESS, (param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;

                if (config != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"编辑配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                    };
                    _sysLogService.AddSysLogAsync(log);

                    _modifyLogService.AddAsync(new ModifyLog
                    {
                        Id         = Guid.NewGuid().ToString("N"),
                        ConfigId   = config.Id,
                        Key        = config.Key,
                        Group      = config.Group,
                        Value      = config.Value,
                        ModifyTime = config.UpdateTime.Value
                    });
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.EDIT_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;

                if (config != null)
                {
                    if (config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Update,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            },
                            OldItem = new ConfigItem {
                                group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                            }
                        };
                        var nodes = await _serverNodeService.GetAllNodesAsync();
                        foreach (var node in nodes)
                        {
                            if (node.Status == NodeStatus.Offline)
                            {
                                continue;
                            }
                            await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                        }
                    }
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.DELETE_CONFIG_SUCCESS, (param) =>
            {
                var config = param as Config;
                if (config != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"删除配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.DELETE_CONFIG_SUCCESS, async(param) =>
            {
                var config = param as Config;
                if (config != null)
                {
                    var action = await CreateRemoveWebsocketAction(config, config.AppId);
                    var nodes  = await _serverNodeService.GetAllNodesAsync();
                    foreach (var node in nodes)
                    {
                        if (node.Status == NodeStatus.Offline)
                        {
                            continue;
                        }
                        await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                    }
                }
            });

            TinyEventBus.Instance.Regist(EventKeys.OFFLINE_CONFIG_SUCCESS, (param) =>
            {
                var config = param as Config;
                if (config != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"下线配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.OFFLINE_CONFIG_SUCCESS, async(param) =>
            {
                var config = param as Config;
                if (config != null)
                {
                    //notice clients the config item is offline
                    var action = new WebsocketAction {
                        Action = ActionConst.Remove, Item = new ConfigItem {
                            group = config.Group, key = config.Key, value = config.Value
                        }
                    };
                    var nodes = await _serverNodeService.GetAllNodesAsync();
                    foreach (var node in nodes)
                    {
                        if (node.Status == NodeStatus.Offline)
                        {
                            continue;
                        }
                        await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                    }
                }
            });


            TinyEventBus.Instance.Regist(EventKeys.PUBLISH_CONFIG_SUCCESS, (param) =>
            {
                Config config = param as Config;

                if (config != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"上线配置【Key:{config.Key}】【Value:{config.Value}】【Group:{config.Group}】【AppId:{config.AppId}】"
                    };
                    _sysLogService.AddSysLogAsync(log);
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.PUBLISH_CONFIG_SUCCESS, async(param) =>
            {
                Config config = param as Config;

                if (config != null)
                {
                    if (config != null && config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients config item is published
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Add,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            }
                        };
                        var nodes = await _serverNodeService.GetAllNodesAsync();
                        foreach (var node in nodes)
                        {
                            if (node.Status == NodeStatus.Offline)
                            {
                                continue;
                            }
                            await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                        }
                    }
                }
            });


            TinyEventBus.Instance.Regist(EventKeys.ROLLBACK_CONFIG_SUCCESS, (param) =>
            {
                dynamic param_dy    = param;
                Config config       = param_dy.config;
                ModifyLog modifyLog = param_dy.modifyLog;

                if (config != null && modifyLog != null)
                {
                    var log = new SysLog
                    {
                        LogTime = DateTime.Now,
                        LogType = SysLogType.Normal,
                        AppId   = config.AppId,
                        LogText = $"回滚配置【Key:{config.Key}】 【Group:{config.Group}】 【AppId:{config.AppId}】至历史记录:{modifyLog.Id}"
                    };
                    _sysLogService.AddSysLogAsync(log);

                    _modifyLogService.AddAsync(new ModifyLog
                    {
                        Id         = Guid.NewGuid().ToString("N"),
                        ConfigId   = config.Id,
                        Key        = config.Key,
                        Group      = config.Group,
                        Value      = config.Value,
                        ModifyTime = config.UpdateTime.Value
                    });
                }
            });
            TinyEventBus.Instance.Regist(EventKeys.ROLLBACK_CONFIG_SUCCESS, async(param) =>
            {
                dynamic param_dy = param;
                Config config    = param_dy.config;
                Config oldConfig = param_dy.oldConfig;

                ModifyLog modifyLog = param_dy.modifyLog;

                if (config != null && oldConfig != null)
                {
                    if (config.OnlineStatus == OnlineStatus.Online)
                    {
                        //notice clients
                        var action = new WebsocketAction
                        {
                            Action = ActionConst.Update,
                            Item   = new ConfigItem {
                                group = config.Group, key = config.Key, value = config.Value
                            },
                            OldItem = new ConfigItem {
                                group = oldConfig.Group, key = oldConfig.Key, value = oldConfig.Value
                            }
                        };
                        var nodes = await _serverNodeService.GetAllNodesAsync();
                        foreach (var node in nodes)
                        {
                            if (node.Status == NodeStatus.Offline)
                            {
                                continue;
                            }
                            await _remoteServerNodeProxy.AppClientsDoActionAsync(node.Address, config.AppId, action);
                        }
                    }
                }
            });
        }