我们有两个 Service Fabric 无状态服务。我们已将 Service Fabric 运行时升级到最新版本,现在想使用最新的 V2(V2_1) 运行时进行通信。我们还将 Service Fabric SDK 升级到了最新版本。
- 数学服务。它有两个暴露于通信的端点。
- EvilMathTeacherService。它调用这两个端点来做一些事情。它还暴露了一个端点。
这两个服务可以使用最新的 V2(V2_1) 运行时相互通信。我们有另一个应用程序,一个 WinForm 应用程序,它想要调用 EvilMathTeacherService 来让它做一些坏事。问题是当我们使用 V2(V2_1) 运行时从位于结构集群外部的这个 Winform 应用程序调用服务结构服务时,它不起作用。它不做任何事情。
所以我的问题是——我能做些什么来实现它吗?或者在最新的 V2(V2_1) 运行时中是否无法从外部与服务进行通信?我们可以使用 V1 运行时来做到这一点,而且在旧的 V1 运行时中它完全没问题。
代码示例:(相关部分)
服务 1:MathService.cs
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(
context => new FabricTransportServiceRemotingListener(
context,
_mathCalculator_v2,
new FabricTransportRemotingListenerSettings()
{
EndpointResourceName = "MathCalculator_v2"
}),
"MathCalculator_v2"),
new ServiceInstanceListener(
context => new FabricTransportServiceRemotingListener(
context,
_textManipulator_v2,
new FabricTransportRemotingListenerSettings()
{
EndpointResourceName = "TextManipulator_v2"
}),
"TextManipulator_v2")
};
}
服务清单:
<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 Name="ServiceEndpointV2_1" />
</Endpoints>
服务 2:EvilMathTeacherService.cs
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(
context => new FabricTransportServiceRemotingListener(
context,
_questionnaire,
new FabricTransportRemotingListenerSettings()
{
EndpointResourceName = "Questionnaire_v2"
}),
"Questionnaire_v2")
};
}
在 RunAsync 方法中:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.
long iterations = 0;
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
ServiceEventSource.Current.ServiceMessage(this.Context, "Evil teacher is coming to get you!-{0}", ++iterations);
Random r = new Random();
int first = r.Next(0, 100);
var second = r.Next(200, 400);
try
{
var sum = await _questionnaire.AddTwoNumbers(first, second);
ServiceEventSource.Current.ServiceMessage(this.Context, "Evil Math teacher says - Sum-{0}", sum);
var ifEqual = await _questionnaire.CheckIfTwoNumbersAreEqual(first, second);
ServiceEventSource.Current.ServiceMessage(this.Context, "Evil Math teacher says - If Equal-{0}", ifEqual);
}
catch (Exception ex)
{
throw;
}
await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken);
}
}
这是调用 MathService 的 Questionnaire.cs 类
public async Task<int> AddTwoNumbers(int a, int b)
{
var uri = new Uri("fabric:/SampleSFV2/MathService");
var proxyFactory = new ServiceProxyFactory((c) =>
{
var settings = new FabricTransportRemotingSettings();
return new FabricTransportServiceRemotingClientFactory(settings);
});
var service = proxyFactory.CreateServiceProxy<IMathCalculator>(uri, listenerName: "MathCalculator_v2");
return await service.Add(a, b);
}
public async Task<bool> CheckIfTwoNumbersAreEqual(int a, int b)
{
var text1 = a.ToString();
var text2 = b.ToString();
var uri = new Uri("fabric:/SampleSFV2/MathService");
var proxyFactory = new ServiceProxyFactory((c) =>
{
var settings = new FabricTransportRemotingSettings();
return new FabricTransportServiceRemotingClientFactory(settings);
});
var service = proxyFactory.CreateServiceProxy<ITextManipulator>(uri, listenerName: "TextManipulator_v2");
return await service.IfEqual(text1, text2);
}
这按预期工作。但是,当我从我的 winform 应用程序对 EvilMathTeacherService 或 MathService 本身进行类似调用时,该调用似乎并没有到达服务。
Winform应用部分:Form1.cs
private async void button_AddNumbers_Click(object sender, EventArgs e)
{
//int number1 = int.Parse(textBox_Number1.Text);
//int number2 = int.Parse(textBox_Number2.Text);
//var uri = _evilMathServiceUri;
int number1 = 10;
int number2 = 100;
var uri = new Uri("fabric:/SampleSFV2/EvilMathTeacherService");
ServiceProxyFactory proxyFactory = new ServiceProxyFactory((c) =>
{
FabricTransportRemotingSettings settings = new FabricTransportRemotingSettings();
return new FabricTransportServiceRemotingClientFactory(settings);
});
try
{
IQuestionnaire service = proxyFactory.CreateServiceProxy<IQuestionnaire>(uri, listenerName: "Questionnaire_v2");
int result = await service.AddTwoNumbers(number1, number2);
MessageBox.Show("Result= " + result);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
我从他们的官方文档中关注这个链接- https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting#how-to-use-remoting- v2 堆栈
请指出我在这里遗漏的任何内容。再次断言 - 我在使用 Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime 从结构集群外部的 Winform 应用程序调用服务时遇到问题。
或者这不能再使用 V2 运行时完成?因为我们正在使用 V1 运行时成功地做同样的事情。
示例代码项目: