Azure Service Fabric 服务之间的 Http 通信
Http Communication between Azure Service Fabric services
我的情况:
- 有状态服务
- 作为非 SF 应用程序访问我的有状态服务的端点的无状态 WebAPI。
- 有状态服务和无状态 WebAPI 正在通过 RPC 进行通信。我遵循了本教程 (https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-add-a-web-frontend)
问题:
我正在尝试将有状态服务和无状态 WebAPI 之间的通信从 RPC 更改为 HTTP 通信,因为我想避免使用接口在服务之间进行通信。这甚至可以通过 HTTP 通信实现吗?如果是这样,我的无状态 WebAPI 如何在不使用接口的情况下调用我的有状态应用程序中的特定方法?
更新:
感谢 alltej,我开始阅读更多有关 HttpCommunicationListeners 的内容。本教程 (https://docs.microsoft.com/nl-nl/azure/service-fabric/service-fabric-concepts-partitioning) 很好地解释了 Http 通信。
在下面的代码片段中:"CreateServiceReplicaListeners()" 调用 CreateInternalListener(),然后调用 "ProcessInternalRequest()",最后调用 "AddUserAsync()"。
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[] { new ServiceReplicaListener(context => this.CreateInternalListener(context))};
}
private ICommunicationListener CreateInternalListener(ServiceContext context)
{
EndpointResourceDescription internalEndpoint = context.CodePackageActivationContext.GetEndpoint("ProcessingServiceEndpoint");
string uriPrefix = String.Format(
"{0}://+:{1}/{2}/{3}-{4}/",
internalEndpoint.Protocol,
internalEndpoint.Port,
context.PartitionId,
context.ReplicaOrInstanceId,
Guid.NewGuid());
string nodeIP = FabricRuntime.GetNodeContext().IPAddressOrFQDN;
string uriPublished = uriPrefix.Replace("+", nodeIP);
return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInternalRequest);
}
private async Task ProcessInternalRequest(HttpListenerContext context, CancellationToken cancelRequest)
{
string output = null;
string user = context.Request.QueryString["lastname"].ToString();
try
{
output = await this.AddUserAsync(user);
}
catch (Exception ex)
{
output = ex.Message;
}
using (HttpListenerResponse response = context.Response)
{
if (output != null)
{
byte[] outBytes = Encoding.UTF8.GetBytes(output);
response.OutputStream.Write(outBytes, 0, outBytes.Length);
}
}
}
private async Task<string> AddUserAsync(string user)
{
IReliableDictionary<String, String> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<String, String>>("dictionary");
using (ITransaction tx = this.StateManager.CreateTransaction())
{
bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user);
await tx.CommitAsync();
return String.Format(
"User {0} {1}",
user,
addResult ? "sucessfully added" : "already exists");
}
}
}
MyCustomHttpListener 是一个 class,您必须将其创建为实现 ICommunicationListener 的自定义侦听器。它包含您需要覆盖的三个方法。请参阅此处的 OwinCommunicationListener 示例:https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-webapi
我的情况:
- 有状态服务
- 作为非 SF 应用程序访问我的有状态服务的端点的无状态 WebAPI。
- 有状态服务和无状态 WebAPI 正在通过 RPC 进行通信。我遵循了本教程 (https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-add-a-web-frontend)
问题:
我正在尝试将有状态服务和无状态 WebAPI 之间的通信从 RPC 更改为 HTTP 通信,因为我想避免使用接口在服务之间进行通信。这甚至可以通过 HTTP 通信实现吗?如果是这样,我的无状态 WebAPI 如何在不使用接口的情况下调用我的有状态应用程序中的特定方法?
更新:
感谢 alltej,我开始阅读更多有关 HttpCommunicationListeners 的内容。本教程 (https://docs.microsoft.com/nl-nl/azure/service-fabric/service-fabric-concepts-partitioning) 很好地解释了 Http 通信。
在下面的代码片段中:"CreateServiceReplicaListeners()" 调用 CreateInternalListener(),然后调用 "ProcessInternalRequest()",最后调用 "AddUserAsync()"。
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[] { new ServiceReplicaListener(context => this.CreateInternalListener(context))};
}
private ICommunicationListener CreateInternalListener(ServiceContext context)
{
EndpointResourceDescription internalEndpoint = context.CodePackageActivationContext.GetEndpoint("ProcessingServiceEndpoint");
string uriPrefix = String.Format(
"{0}://+:{1}/{2}/{3}-{4}/",
internalEndpoint.Protocol,
internalEndpoint.Port,
context.PartitionId,
context.ReplicaOrInstanceId,
Guid.NewGuid());
string nodeIP = FabricRuntime.GetNodeContext().IPAddressOrFQDN;
string uriPublished = uriPrefix.Replace("+", nodeIP);
return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInternalRequest);
}
private async Task ProcessInternalRequest(HttpListenerContext context, CancellationToken cancelRequest)
{
string output = null;
string user = context.Request.QueryString["lastname"].ToString();
try
{
output = await this.AddUserAsync(user);
}
catch (Exception ex)
{
output = ex.Message;
}
using (HttpListenerResponse response = context.Response)
{
if (output != null)
{
byte[] outBytes = Encoding.UTF8.GetBytes(output);
response.OutputStream.Write(outBytes, 0, outBytes.Length);
}
}
}
private async Task<string> AddUserAsync(string user)
{
IReliableDictionary<String, String> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<String, String>>("dictionary");
using (ITransaction tx = this.StateManager.CreateTransaction())
{
bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user);
await tx.CommitAsync();
return String.Format(
"User {0} {1}",
user,
addResult ? "sucessfully added" : "already exists");
}
}
}
MyCustomHttpListener 是一个 class,您必须将其创建为实现 ICommunicationListener 的自定义侦听器。它包含您需要覆盖的三个方法。请参阅此处的 OwinCommunicationListener 示例:https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-webapi