private static void ShellEvents_DependencyRegistering(SchubertOptions option, DependencySetupEventArgs eventArgs) { //这里捞出要注册的服务。 if (TryGetRemoteService(eventArgs.ActualDependency, option, out RemoteServiceAttribute remoteAttribute)) { _serviceExports.Add(new SwiftyServiceDescriptor(eventArgs.ActualDependency.ServiceType, remoteAttribute.Version.IfNullOrWhiteSpace("1.0.0"))); } }
//使用这个事件注册,确保之前的服务端已经注册,这样我们通过 TryAdd 语义排除掉已经注册的服务端接口。 private static void ShellEvents_ShellInitialized(SchubertOptions options, Framework.Environment.ShellBuilders.ShellContext context) { if (_clientExports != null /*&& _clientExports.Count > 0*/) { context.RegisteredServices.AddSmart(_clientExports); context.RegisteredServices.AddSingleton <SwiftyClientManager, SwiftyClientManager>(); } }
public ShellDescriptorManager( IRepository <ShellDescriptorRecord> repository, IOptions <SchubertOptions> options) { Guard.ArgumentNotNull(options, nameof(options)); Guard.ArgumentNotNull(repository, nameof(repository)); _repository = repository; _options = options.Value; }
private static bool TryGetRemoteService(ServiceDescriptor serverTypeDesc, SchubertOptions options, out RemoteServiceAttribute attribute) { if (serverTypeDesc.ServiceType.TryGetRemoteServiceAttribute(true, out attribute)) { if (!attribute.VipAddress.CaseInsensitiveEquals($"{options.Group}.{options.AppSystemName}")) { var svcType = serverTypeDesc.ServiceType.GetTypeInfo(); String optionsName = nameof(SchubertOptions); throw new SwiftyApplicationException($"{nameof(RemoteServiceAttribute)} 的属性" + $" {nameof(RemoteServiceAttribute.VipAddress)} 必须使用 [{optionsName}.{nameof(SchubertOptions.Group)}].[{optionsName}.{nameof(SchubertOptions.AppSystemName)}] (区分大小写)格式。{System.Environment.NewLine}" + $"类型 '{svcType.FullName}' 或程序集 '{svcType.Assembly.FullName}' 上的 {nameof(RemoteServiceAttribute)} 不满足该要求。"); } return(true); } return(false); }
public ShellContextFactory( IShellDescriptorCache shellDescriptorCache, IShellDescriptorManager shellDescriptorManager, ICompositionStrategy compositionStrategy, IOptions <SchubertOptions> options, ILoggerFactory loggerFactory) { Guard.ArgumentNotNull(shellDescriptorManager, nameof(shellDescriptorManager)); Guard.ArgumentNotNull(shellDescriptorCache, nameof(shellDescriptorCache)); Guard.ArgumentNotNull(compositionStrategy, nameof(compositionStrategy)); Guard.ArgumentNotNull(options, nameof(options)); _options = options.Value; _compositionStrategy = compositionStrategy; _shellDescriptorManager = shellDescriptorManager; _shellDescriptorCache = shellDescriptorCache; _logger = loggerFactory?.CreateLogger <ShellContextFactory>() ?? (ILogger)NullLogger.Instance; }
private void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider obj) { this.Load(); }
private static void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider serviceProvider) { var schedulingServer = serviceProvider.GetRequiredService <ISchedulingServer>(); schedulingServer.ScheduleAsync().GetAwaiter().GetResult(); }
private static void ShellEvents_EngineStarted(SchubertOptions options, IServiceProvider serviceProvider) { ILoggerFactory loggerFactory = serviceProvider.GetRequiredService <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger("Schubert"); //这里启动 Swifty 服务端。 if (!(_serviceExports?.IsEmpty ?? true)) //其实不可能为空,防止手贱的反射该方法报错。 { IOptions <SwiftyOptions> swiftyOptions = serviceProvider.GetRequiredService <IOptions <SwiftyOptions> >(); IOptions <NetworkOptions> netOptions = serviceProvider.GetRequiredService <IOptions <NetworkOptions> >(); /*************** * * 地址是个棘手的问题 * * 1、bindingAddress 为指定的 ip 地址: * 此时我们默认使用这个绑定地址即是他想要注册的地址。 * * 2、考虑 bindingAddress 为空的情况: * 为空时候认为他要使用 network 配置,如果要使用 binding any 必须显式设置为 0.0.0.0 * 因此,当 bindingAddress 为空时候我们就默认也注册 network 配置的地址 * * 3、再来一种情况,考虑 bindingAddress 设置为 any(即 0.0.0.0) : * 这时候总不能向注册中心去注册 0.0.0.0 吧 * 因此提供一个 public address 单独作为注册地址才能完整的解决问题 * 考虑当 public address 为空,bind address 指定了 0.0.0.0: * 这种情况直接再读一次 network 配置,认为他要 bind 端口是本机所有网卡,但是只注册 network 的配置。 * * 似乎没有什么逻辑漏洞,有的话 Swifty 里会再次为我们检查,详情见 swifty 实现。 * ***************/ if (swiftyOptions.Value.Server.BindingAddress.IsNullOrWhiteSpace()) { swiftyOptions.Value.Server.BindingAddress = GetNetworkAddress(netOptions); } var address = swiftyOptions.Value.Server.PublicAddress.IfNullOrWhiteSpace(swiftyOptions.Value.Server.BindingAddress); address = address.CaseSensitiveEquals("0.0.0.0") ? GetNetworkAddress(netOptions) : address; bool enableEureka = !String.IsNullOrWhiteSpace(swiftyOptions.Value.Server.Eureka.EurekaServerServiceUrls); if (address.IsNullOrWhiteSpace() && enableEureka) { string optionProperty = $"{nameof(SwiftyOptions)}.{nameof(SwiftyOptions.Server)}.{nameof(ExtendedSwiftyServerOptions.PublicAddress)}"; string bindProperty = $"{nameof(SwiftyOptions)}.{nameof(SwiftyOptions.Server)}.{nameof(ExtendedSwiftyServerOptions.BindingAddress)}"; string error = $"无法确定 Swifty 服务要发布的地址,考虑以下三种方式:{System.Environment.NewLine}" + $"1、请使用 '{nameof(NetworkOptions)}' 配置本机网络。{System.Environment.NewLine}" + $"2、使用 '{optionProperty}' 属性配置注册地址。{System.Environment.NewLine}" + $"3、通过'{bindProperty}' 属性指定明确的 TCP 绑定地址。{System.Environment.NewLine}"; throw new SchubertException(error); } InstanceDescription desc = new InstanceDescription($"{options.AppSystemName}", $"{options.Group}.{options.AppSystemName}", address); IServiceLocator locator = new SchubertServiceLocator(loggerFactory); SwiftyBootstrap boot = new SwiftyBootstrap(locator, swiftyOptions.Value.Server, desc, loggerFactory); var servies = _serviceExports.ToArray(); //其实也清理不了什么,上一步的对象已经被引用了,清理一个 ConcurrentBag 结构吧。 _serviceExports = null; boot .Handles(handlers => handlers.Add(new ScopeInjectionEventHandler())) .EurekaConfig(swiftyOptions.Value.Server.EnableEureka, swiftyOptions.Value.Server.Eureka) .AddServices(servies) .Bind(address, swiftyOptions.Value.Server.Port) .StartAsync().ContinueWith(s => { if (s.Exception != null) { logger.WriteError(0, "启动 swifty 服务器发生错误。", s.Exception); } else { logger.WriteInformation(0, $"swifty 服务器已经启动。{System.Environment.NewLine}" + $"(port: {s.Result.Port}, services: {servies.Length}, eureka: {enableEureka.ToString().ToLower()})。"); } }); } else { logger.WriteWarning($"开启了 Swifty 服务端功能,但是没有发现可用的 Swifty 服务,是否在接口上遗漏了 {nameof(RemoteServiceAttribute)} 或 {nameof(ThriftServiceAttribute)}。"); } }
private void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider serviceProvider) { var client = this.CreateOrGetZookeeperClient(); this.LoadRemoteConfigurationAsync(client, true).GetAwaiter().GetResult(); }