你如何公开远程服务?

时间:2018-02-23 15:52:11

标签: c# .net asp.net-web-api visual-studio-2017 azure-service-fabric

问题

是否可以在没有第二个参数FabricTransportServiceRemotingListener的情况下实例化IService

背景

Service Fabric允许您公开多个远程端点,您可以通过这些端点从外部服务查询服务。例如,以下代码将通过2个不同的端点公开此服务:

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener(serviceContext => new FabricTransportServiceRemotingListener(serviceContext,
                new AccountService(),
                new FabricTransportRemotingListenerSettings
                {
                    EndpointResourceName = "AccountsRemotingListenerEndpoint"
                }), "AccountsRemotingListenerEndpoint"),
            new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(Startup.ConfigureApp,
                serviceContext, ServiceEventSource.Current, "ServiceEndpointHttps"))
        };
    }

这使我们能做什么 吗

外部AccountService的服务现在可以调用AccountService方法,就好像它们是本地方法一样。示例用法是:

    public async Task<AccountModel> GetAccount(Guid id)
    {
        var proxy = ServiceProxy.Create<IAccountService>(new Uri(Client.AccountserviceUrl),
            new ServicePartitionKey(), listenerName: "AccountsRemotingListenerEndpoint");
        var result = await proxy.GetAccount(id);
        var account = new AccountModel
        {
            AccountId = result.AccountId.Value,
            Name = result.Name
        };

        return account;
    }

深入挖掘:为什么我要排除IService参数?

我很高兴你问过。

我们尝试公开的服务只是SharpReverseProxy的一种实现。其中没有服务代码。

这只是Startup.cs中的Web API配置代码:

public void Configure(IApplicationBuilder app, 
    IHostingEnvironment env, 
    ILoggerFactory loggerFactory) {

    app.UseProxy(new List<ProxyRule> {
        new ProxyRule {
            Matcher = uri => uri.AbsoluteUri.Contains("/api/"),
            Modifier = (req, user) => {
                var match = Regex.Match(req.RequestUri.AbsolutePath, "/api/(.+)service");
                req.RequestUri = new Uri(string.Format("http://{0}.{1}/{2}",
                    match.Groups[1].Value,
                    req.RequestUri.Host,
                    req.RequestUri.AbsolutePath.Replace(match.Value, "/api/")
                ));
            },
            RequiresAuthentication = true
        }
    },
    r => {
        _logger.LogDebug($"Proxy: {r.ProxyStatus} Url: {r.OriginalUri} Time: {r.Elapsed}");
        if (r.ProxyStatus == ProxyStatus.Proxied) {
            _logger.LogDebug($"        New Url: {r.ProxiedUri.AbsoluteUri} Status: {r.HttpStatusCode}");
        }
    });
}

假设此代码是单独服务的一部分,我们如何通过FabricTransportServiceRemotingListener公开它,尽管它没有服务类?

是否可以在没有第二个参数FabricTransportServiceRemotingListener的情况下实例化IService

这是本地的。

0 个答案:

没有答案