Frage

Have an application that communicates over Terminal Services / Remote Desktop Services Virtual Channel API. Randomly and periodically (about every 20,000 messages), a message will be sent by the client (VirtualChannelWrite returns 0, and VirtualChannelOpenEvent is called with CHANNEL_EVENT_WRITE_COMPLETE) but the message is never read by the server call to WTSVirtualChannelRead. There are no error messages on the server. There is no indication of timing differences on the client side write.

On the server side, the virtual channel is only accessed from one thread for reading and writing, so it is not a threading issue (WTSVirtualChannelRead and WTSVirtualChannelWrite are not thread safe).

Anyone have insight as to what is causing lost messages?

I wonder if this API simply doesn't scale for high density client-to-server traffic (never seen a dropped message from server to client). I wonder if an overlapped I/O solution on the server would perform better, per MSDN: "WTSVirtualChannelQuery returns a file handle that you can use to perform asynchronous (overlapped) read and write operations".

War es hilfreich?

Lösung

WTSVirtualChannelRead and WTSVirtualChannelWrite API are one of the badly designed API by Microsoft.

First, you cannot use WTSVirtualChannelRead() and WTSVirtualChannelWrite() from any thread due to the asynchronous I/O. You have to use WTSVirtualChannelQuery() to obtain the file handle and then you do reads and writes to the Virtual Channel via ReadFile() and WriteFile().

Also when reading the Virtual Channel, you have to handle you have to handle situations where ReadFile() returns immediately because there is data available and ReadFile() which is blocked and you wait until the I/O completes and then call GetOverLappedResult().

For more details follow http://blogs.msdn.com/b/rds/archive/2007/09/20/dynamic-virtual-channels.aspx

Andere Tipps

Angry Coder's answer is correct that you have to use Overlapped I/O. I found a solution that varies a little in the details:

First, as I mentioned in my question, WTSVirtualChannelRead() and WTSVirtualChannelWrite() generally work as long as they're called in the same thread. But still WTSVirtualChannelRead() will occasionally miss messages. Apparently the workaround is to block for 1 sec. No good when you need to write, but can't while the read is blocking.

Second, I implemented Overlapped I/O in .NET according to this article. With I/O completion ports, the read and write always complete in the callback method, so no need to distinguish whether there is or isn't data available.

Third, it isn't necessary to implement Dynamic Virtual Channels; it all works just fine with static channels per the Virtual Channel Client API.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top