ベンダーソフトウェアクライアントが接続するWindowsサービスとして動作するTcpListenerサービスを作成しています。私はクライアントの実装を変更することはできず、その仕様に従わなければなりません。TcpListenerがハートビートを5秒ごとに送信し、クライアントasyncからメッセージを読み取る
メッセージを受信して応答を返す部分があります。私が持っている問題は、クライアントが同じメッセージで応答するハートビートメッセージ(S0000E
)が5秒ごとに送信されることを期待することです。クライアントから受信した実際のメッセージを処理するために、非同期/待機中の機能の中にその機能を追加する方法がわかりません。
のOnStart
_serverListenerTask = Task.Run(() => AcceptClientsAsync(_listener, _cancellationToken.Token));
AcceptClientsAsync
static async Task AcceptClientsAsync(TcpListener listener, CancellationToken ct)
{
var clientCounter = 0;
while (!ct.IsCancellationRequested)
{
TcpClient client = await listener.AcceptTcpClientAsync()
.ConfigureAwait(false);
clientCounter++;
await ReceiveMessageAsync(client, clientCounter, ct);
}
}
私はTask.WhenAny
にハートビートタスクを追加することができると思ったが、それは、ハートビートに常に火災やIを引き起こし
static async Task ReceiveMessageAsync(TcpClient client, int clientIndex, CancellationToken ct)
{
Log.Info("New client ({0}) connected", clientIndex);
using (client)
{
var buffer = new byte[4096];
var stream = client.GetStream();
while (!ct.IsCancellationRequested)
{
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(15));
var amountReadTask = stream.ReadAsync(buffer, 0, buffer.Length, ct);
var completedTask = await Task.WhenAny(timeoutTask, amountReadTask)
.ConfigureAwait(false);
if (completedTask == timeoutTask)
{
var msg = Encoding.ASCII.GetBytes("Client timed out");
await stream.WriteAsync(msg, 0, msg.Length);
break;
}
var bytesRead = amountReadTask.Result;
if (bytesRead == 0)
{
// Nothing was read
break;
}
// Snip... Handle message from buffer here
await stream.WriteAsync(responseBuffer, 0, responseBuffer.Length, ct)
.ConfigureAwait(false);
}
}
Log.Info("Client ({0}) disconnected", clientIndex);
}
ReceiveMessageAsyncその応答を決して読むことはできませんでした。私はまた、タイムアウトの前にハートビートを送信しようとしましたが、それは送信のために働くタスクを読んでいましたが、次にハートビートの応答を読んでいました。本質的に、ハートビート交換が成功した場合、その15秒後にクライアントを切断しないでください。
あなたはどのようにして、リソースでより効率的にそれを改善する場合は、実装の仕方以下、現実的な解決策になることができますあるメッセージと別のメッセージを分離しますか? – john
私は通常、このプロトコルはクライアント要求 - >サーバー応答ですが、この特定のインスタンスではサーバーハートビート - >クライアントハートビートであることを読んでいますか?プロトコルに特定のルールがありますか?応答が未処理の間にハートビートメッセージを送信することは許可されていませんか?ここに含まれるメッセージ(種類)とそれを取り巻く規則(すなわち「プロトコル」)の明確な定義が役立ちます。 –
クライアントが要求を送信するのとまったく同じ瞬間にサーバーがハートビートを送信することを選択した場合、それは本質的に難しいようです。 –