1

ターミナル サービス/リモート デスクトップ サービス仮想チャネル API を介して通信するアプリケーションを用意します。ランダムかつ定期的に (約 20,000 メッセージごとに)、メッセージがクライアントによって送信されます (VirtualChannelWrite は 0 を返し、VirtualChannelOpenEvent は CHANNEL_EVENT_WRITE_COMPLETE で呼び出されます) が、メッセージは WTSVirtualChannelRead へのサーバー呼び出しによって読み取られることはありません。サーバーにエラー メッセージはありません。クライアント側の書き込みでタイミングの違いは示されません。

サーバー側では、仮想チャネルは読み取りと書き込みのために 1 つのスレッドからのみアクセスされるため、スレッドの問題ではありません (WTSVirtualChannelRead と WTSVirtualChannelWrite はスレッド セーフではありません)。

失われたメッセージの原因について洞察を持っている人はいますか?

この API は、高密度のクライアントからサーバーへのトラフィックに対応していないのでしょうか (サーバーからクライアントへのメッセージのドロップは見られませんでした)。MSDNによると、サーバー上のオーバーラップ I/O ソリューションのパフォーマンスが向上するかどうか疑問に思っています。

4

2 に答える 2

1

WTSVirtualChannelRead および WTSVirtualChannelWrite API は、Microsoft によって設計が不適切な API の 1 つです。

まず、非同期 I/O のため、どのスレッドからでも WTSVirtualChannelRead() と WTSVirtualChannelWrite() を使用できません。WTSVirtualChannelQuery() を使用してファイル ハンドルを取得する必要があります。その後、ReadFile() および WriteFile() を介して仮想チャネルへの読み取りと書き込みを行います。

また、仮想チャネルを読み取るときは、ReadFile() がすぐに返される状況を処理する必要があります。これは、使用可能なデータがあり、ブロックされている ReadFile() があり、I/O が完了するまで待ってから GetOverLappedResult() を呼び出す場合です。

詳細については、http://blogs.msdn.com/b/rds/archive/2007/09/20/dynamic-virtual-channels.aspxを参照してください。

于 2013-05-09T09:03:52.447 に答える
1

Overlapped I/O を使用する必要があるというAngry Coder の回答は正しいです。詳細が少し異なる解決策を見つけました:

まず、質問で述べたように、WTSVirtualChannelRead() と WTSVirtualChannelWrite() は通常、同じスレッドで呼び出されている限り機能します。ただし、それでも WTSVirtualChannelRead() はメッセージを見逃すことがあります。どうやら回避策は1 秒間ブロックすることです。書き込みが必要な場合はダメですが、読み取りがブロックされている間はできません。

次に、この記事に従って、.NET にオーバーラップ I/O を実装しました。I/O 完了ポートを使用すると、読み取りと書き込みは常にコールバック メソッドで完了するため、使用可能なデータがあるかどうかを区別する必要はありません。

第 3 に、動的仮想チャネルを実装する必要はありません。Virtual Channel Client APIごとに、静的チャネルで問題なく動作します。

于 2013-05-22T17:18:07.130 に答える