试图简要介绍如何在 ASP.NET Core 项目中使用 SF5.5 和 SDK2.5 (3/2017) 让 http 和 https 在本地机器上工作。我展示了代码和配置,并列出了所有页面作为信息来源的参考。我一个人不可能做到这一点。感谢社区!
第 1 步:
为要使用的本地 SF 集群创建证书。我喜欢这个 article 创建证书。然后我使用 certmgr 提取证书指纹以获取证书详细信息。
提示:当您从证书存储中复制指纹时,它将不起作用,我将其复制到记事本和 Visual Studio Code 中,然后再将其粘贴到配置中。 TChaing 的这个引用here 表明存在隐藏字符。我只是简单地输入了它(没有空格)。我知道证书有问题,因为事件查看器有错误消息表明无法解析证书,这导致我得到了这个答案。
第二步:
对于我的应用程序和服务清单,Matt Kotsenas 的文章 https://matt.kotsenas.com/posts/https-in-service-fabric-web-api 非常棒。他还有一个优雅的解决方案来创建侦听器,只需稍加调整即可与我的代码清单中的 ASP.Net Core 一起使用。
代码:
应用程序清单文件
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Web1Pkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<!-- Add policies for service endpoints -->
<Policies>
<EndpointBindingPolicy EndpointRef="ServiceEndpointHttps" CertificateRef="MyCert" />
</Policies>
...
</DefaultServices>
<!-- Add the certificate. In production use parameter references to the thumbprints. -->
<Certificates>
<EndpointCertificate X509FindValue="6e6a28c083c1b8114c4e2279b37cf6d684668aad" Name="MyCert" />
</Certificates>
</ApplicationManifest>
ServiceManifest 文件
...
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8340" />
<Endpoint Protocol="https" Name="ServiceEndpointHttps" Type="Input" Port="8343" />
</Endpoints>
在这种情况下,来自我的服务类“Web1”的 C# 代码。有两种不同的方法可以创建如下所示的侦听器。注释代码直接命名了“ServiceEndpoint”等监听器,并注意“HttpListner1”。这是 ASP.NET Core 中的新功能。如果您有多个端点,则必须对其进行专门命名。如果未提供名称,ServiceEndpoint 不会自动成为名称。
未注释的代码使用提取来获取服务名称,然后创建侦听器。在这种情况下,我使用“端点”变量来根据需要为侦听器添加显式名称。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
//return new ServiceInstanceListener[]
//{
// new ServiceInstanceListener(serviceContext =>
// new WebListenerCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
// {
// ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
// return new WebHostBuilder().UseWebListener()
// .ConfigureServices(
// services => services
// .AddSingleton<StatelessServiceContext>(serviceContext))
// .UseContentRoot(Directory.GetCurrentDirectory())
// .UseStartup<Startup>()
// .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
// .UseUrls(url)
// .Build();
// }), "HttpListner1"),
// new ServiceInstanceListener(serviceContext =>
// new WebListenerCommunicationListener(serviceContext, "ServiceEndpointHttps", (url, listener) =>
// {
// ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
// return new WebHostBuilder().UseWebListener()
// .ConfigureServices(
// services => services
// .AddSingleton<StatelessServiceContext>(serviceContext))
// .UseContentRoot(Directory.GetCurrentDirectory())
// .UseStartup<Startup>()
// .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
// .UseUrls(url)
// .Build();
// }), "HttpsListner1")
//};
var endpoints = Context.CodePackageActivationContext.GetEndpoints()
.Where(endpoint => endpoint.Protocol == EndpointProtocol.Http || endpoint.Protocol == EndpointProtocol.Https)
.Select(endpoint => endpoint.Name);
var eps = endpoints.Select(endpoint =>
new ServiceInstanceListener(serviceContext =>
new WebListenerCommunicationListener(serviceContext, endpoint, (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
return new WebHostBuilder().UseWebListener()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}
), endpoint));
return eps;
}
我希望这会为您带来所有缺失的部分。