TCPリクエストをリッスンし、メッセージを信頼できるキューにポップするステートフルサービスファブリックアプリケーションを設定する必要があります。AzureサービスファブリックでTCPを設定する
HTTPとWCFエンドポイントの例はたくさんありますが、単純なTCPでは何も見つかりません。
私はこの<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>
は私がまた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?
}
}
呼ばStatefulService
だから私の質問を持って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();
}
}
と呼ばれるICommunicationListener
を実装してリスナーを持っている必要があり、私のServiceManifest.xml
で
受信しているメッセージをどのように取得するのですか?
の方法でTcpListener
を作成する必要がありますか。ListenerService
?その場合、ServiceManifest.xml
にエンドポイントを指定するポイントは何ですか?
OR
私はOpenAsync
が呼び出されたときに、あなたの通信リスナーコードのみがウリを公開し今TcpCommunicationListener?
私はconfig内のエンドポイントを指定すると自動的にリスナーを開くと仮定しました。 – MrBliz
いいえ、あなた自身のリスナーを開く必要があります。エンドポイントの設定では、1)ポートを指定するとファイアウォールを通過できるようになり、2)http.sysベースのリスナーを使用している場合は、リスナーのURLがACLされます。 –