2016-08-03 2 views
2

У меня есть требование настроить приложение Stateful Service Fabric, которое прослушивает TCP-запросы, а затем выводит сообщения в надежную очередь.Настройка TCP на Azure Service Fabric

Существует множество примеров для конечных точек HTTP и WCF, но я ничего не могу найти для простого TCP.

В моей ServiceManifest.xml я это

<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="ServiceEndpoint" /> 

    <!-- This endpoint is used by the replicator for replicating the state of your service. 
     This endpoint is configured through a ReplicatorSettings config section in the Settings.xml 
     file under the ConfigPackage. --> 
    <Endpoint Name="ReplicatorEndpoint" /> 
    <Endpoint Name="tcpEndpoint" Protocol="tcp" Port="10100"/> 
</Endpoints> 

Я слушатель, который реализует ICommunicationListener называется TcpCommunicationListener

public class TcpCommunicationListener : ICommunicationListener 
{ 
    private readonly ServiceEventSource eventSource; 
    private readonly ServiceContext serviceContext; 
    private readonly string endpointName; 
    private string listeningAddress; 
    private string hostAddress; 


    public TcpCommunicationListener(ServiceContext serviceContext, ServiceEventSource eventSource, string endpointName) 
    { 

     if (serviceContext == null) 
     { 
      throw new ArgumentNullException(nameof(serviceContext)); 
     } 

     if (endpointName == null) 
     { 
      throw new ArgumentNullException(nameof(endpointName)); 
     } 

     if (eventSource == null) 
     { 
      throw new ArgumentNullException(nameof(eventSource)); 
     } 

     this.serviceContext = serviceContext; 
     this.endpointName = endpointName; 
     this.eventSource = eventSource; 
    } 

    public Task<string> OpenAsync(CancellationToken cancellationToken) 
    { 
     var serviceEndpoint = this.serviceContext.CodePackageActivationContext.GetEndpoint(this.endpointName); 
     var protocol = serviceEndpoint.Protocol; 
     int port = serviceEndpoint.Port; 


     //StatefulServiceContext statefulServiceContext = this.serviceContext as StatefulServiceContext; 

     this.hostAddress = FabricRuntime.GetNodeContext().IPAddressOrFQDN; 

     this.listeningAddress = string.Format(
      CultureInfo.InvariantCulture, 
      "{0}://{1}:{2}", 
      protocol, 
      hostAddress, 
      port 
      ); 

     try 
     { 
      this.eventSource.Message("Starting tcp listener " + this.listeningAddress); 

      return Task.FromResult(this.hostAddress); 
     } 
     catch (Exception ex) 
     { 
      this.eventSource.Message("Tcp Listener failed to open endpoint {0}. {1}", this.endpointName, ex.ToString()); 

      throw; 
     } 
    } 

    public Task CloseAsync(CancellationToken cancellationToken) 
    { 
     throw new NotImplementedException(); 
    } 

    public void Abort() 
    { 
     throw new NotImplementedException(); 
    } 
} 

У меня также есть StatefulService под названием ListenerService

internal sealed class ListenerService : StatefulService 
{ 

    public ListenerService(StatefulServiceContext context) 
     : base(context) 
    { 

    } 


    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() 
    { 
     var endpoints = Context.CodePackageActivationContext.GetEndpoints() 
           .Where(endpoint => endpoint.Protocol == EndpointProtocol.Tcp) 
           .Select(endpoint => endpoint.Name); 

     return endpoints.Select(endpoint => new ServiceReplicaListener(
      serviceContext => new TcpCommunicationListener(serviceContext, ServiceEventSource.Current, endpoint), endpoint)); 
    } 


    protected override async Task RunAsync(CancellationToken cancellationToken) 
    { 
     cancellationToken.ThrowIfCancellationRequested(); 

     //do i spin up a TcpListener here? 
    } 
} 

Так мой вопроскак получить полученные сообщения?

Должен ли я создать TcpListener в методе RunAsync моего ListenerService? Если это так, то в чем смысл указывать конечную точку в ServiceManifest.xml?

ИЛИ

Нужно ли мне делать что-то в OpenAsync способе TcpCommunicationListener?

ответ

2

Сейчас ваше сообщение код слушатель публикует только Ури, когда OpenAsync называется. Вам также нужно будет начать прослушивание этой конечной точки. Так, например, вы могли бы открыть Socket в то время. Вы также можете использовать WCF с NetTcpBinding.

+0

Правильно, я предположил, что конечная точка в конфигурации автоматически откроет слушателя. – MrBliz

+1

Нет, вам нужно открыть собственного слушателя. Конфигурация конечной точки выполняет две функции: 1) если вы укажете порт, он разрешит его через брандмауэр и 2) если вы используете прослушиватель http.sys, он будет ACL URL-адресом слушателя. –

Смежные вопросы