我正在尝试构建一个基于Azure Service Fabric的StatefulService的tcp/ip服务器。问题出在本地运行时。 Visual Studio 无法安装服务并出现以下错误:
fabric:/TCPTestServerFabric/TCPTestService is not ready, 1 partitions remaining.
和 Service Fabric Explorer:
Partition is below target replica or instance count.
fabric:/TCPTestServerFabric/TCPTestService 1 1 61eee22a-c5d4-46e8-ab57-8d41009abc3d
N/P InBuild _Node_0 133444395888851522
For more information see: <a href='https://aka.ms/sfhealth' target='_blank'>https://aka.ms/sfhealth</a>
但是...无论如何都安装了它并调试它,就像根本没有问题一样。从 TCP 客户端应用程序中,我了解了如何使用 IP 和端口号连接到服务器并向服务器发送消息并获得响应。我尝试删除 TCPTestService 中 OpenAsync 方法中的代码,但这也没有帮助。还是出现上面的错误。
我检查了我的磁盘空间,没有问题,我有大约 250 GB 的可用空间。 还在 Service Fabric 属性中使用了这些选项之一,但也没有帮助。
有人知道我做错了什么吗? 提前谢谢。
internal sealed class TCPTestService : StatefulService
{
public TCPTestService(StatefulServiceContext context) : base(context) { }
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[] { new ServiceReplicaListener(context =>
new TCPTestServer(context, StateManager), "ServiceEndpoint") };
}
protected override async Task RunAsync(CancellationToken cancellationToken)
{
//cancellationToken.WaitHandle.WaitOne();
}
}
public class TCPTestServer : ICommunicationListener
{
private readonly StatefulServiceContext _context;
private readonly IReliableStateManager _stateManager;
public TCPTestServer(StatefulServiceContext context, IReliableStateManager stateManager)
{
_context = context;
_stateManager = stateManager;
}
public void Abort()
{
ServiceEventSource.Current.ServiceMessage(_context, $"Request aborted");
}
public Task CloseAsync(CancellationToken cancellationToken)
{
ServiceEventSource.Current.ServiceMessage(_context, $"Server closed");
return Task.FromCanceled(cancellationToken);
}
public async Task<string> OpenAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
EndpointResourceDescription serviceEndpoint = _context.CodePackageActivationContext.GetEndpoint("ServiceEndpoint");
int port = serviceEndpoint.Port;
IPEndPoint ipEndPoint = new( IPAddress.Parse( "127.0.0.1" ), port);
using Socket listener = new(
ipEndPoint.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
listener.Bind(ipEndPoint);
listener.Listen();
ServiceEventSource.Current.ServiceMessage(_context, $"Server started");
Socket handler = await listener.AcceptAsync();
ServiceEventSource.Current.ServiceMessage(_context, $"Incoming connection: {handler.AddressFamily}");
while (true)
{
//cancellationToken.ThrowIfCancellationRequested();
// Receive message.
var buffer = new byte[1_024];
var received = await handler.ReceiveAsync(buffer, SocketFlags.None);
var response = Encoding.UTF8.GetString(buffer, 0, received);
if (!string.IsNullOrWhiteSpace(response))
{
ServiceEventSource.Current.ServiceMessage(_context, $"Incoming message: {response}");
var ackMessage = "<ACK/>";
var echoBytes = Encoding.UTF8.GetBytes(ackMessage);
int bytesSent = await handler.SendAsync(echoBytes, 0);
ServiceEventSource.Current.ServiceMessage(_context, $"Sent message: {ackMessage}");
}
else
{
ServiceEventSource.Current.ServiceMessage(_context, $"Disconnected");
break; //Disconnected
}
}
}
catch (Exception ex)
{
ServiceEventSource.Current.ServiceMessage(_context, $"Error: {ex.Message}");
}
}
}
}
只是回答我自己的问题,以防有一天你可能需要它。 摆脱 ICommunicationListener 实现并将 OpenAsync 方法的内容复制到 Stateful 服务实现。您还需要检查侦听器是否已创建。