In a previous blog post, Christa gave a high level explanation of the extensibility points we introduced to Session Broker (SB) in Windows Server 2008. In this post, we will dive a bit deeper to see how we can use SB Extensibility to build our own load balancing logic.
As Christa mentioned, when a new incoming connection is received by a terminal server, the terminal server contacts the SB for directions on where to redirect this new user. To answer this question, the SB must go through its load balancing logic. Our implementation of this logic consists of:
Since the debut of Windows Server 2008, we’ve received some feedback regarding SB load balancing logic, labeling it too simplistic. While this may or may not be the case, with the extensibility points we’ve provided, you can fully replace the SB load logic with your own to load balance based on what might be important to you in your organization.
To implement your own load balancing logic and make use of these extensibility points, you will have to construct a COM server which implements the IWTSSBPlugin interface. This COM server (which I’ll refer to as an “extensibility plug-in”) will be called by the SB for passive notifications as well as requests to make load balancing decisions.
The IWTSSBPlugin interface has five methods which SB calls at different points. We will temporarily ignore WTSSBX_GetUserExternalSession and revisit it in a later blog post.
Let’s quickly review the four methods and when SB calls them:
· Initialize – called by SB when the SB service starts to allow the plug-in to do its initialization.
· Terminated – called by SB when the SB service shuts down to allow the plug-in to do its termination cleanup.
· WTSSBX_GetMostSuitableServer – called by SB when a load balancing decision needs to be made. We can use this method to override the SB’s default load balancing logic.
· WTSSBX_MachineChangeNotification – called by SB when a change occurs in one of the servers in the farm. We can use this method to get information on new terminal servers that have joined or left the farm.
· WTSSBX_SessionChangeNotification – called by SB when a change occurs in a session on a terminal server that is part of the farm. We can use this method to detect session state changes (such as when a user disconnects from his session).
The order in which these methods are called depends on what is happening in the farm. Let’s first look at the machine notifications:
When a server joins a farm the following notifications are called on the plug-in in the following order:
Similarly, when a server leaves the farm WTSSBX_MachineChangeNotification is called with WTSSBX_NOTIFICATION_TYPE set to WTSSBX_NOTIFICATION_REMOVED.
The session notifications are also quite simple:
These notifications provide the plug-in with enough information to make load balancing decisions.
The actual decisions are communicated to the SB via the WTSSBX_GetMostSuitableServer method. Let’s look back at the original explanation of how the SB load balancing logic is invoked to see where in that process WTSSBX_GetMostSuitableServer is called.
When a new connection comes to a terminal server, the server asks the SB to provide the Machine ID of the terminal server which has an existing session for the user. The SB queries its database and if no such session exists, the SB uses its standard load balancing logic to determine a Machine ID to which the user should be redirected. At this point, instead of returning this ID to the terminal server, the SB calls into the plug-in via the WTSSBX_GetMostSuitableServer method and passes the Machine ID it has just calculated as one of the parameters. The plug-in can then change this parameter to redirect to a different terminal server than the one originally intended.
So we see that by returning a different Machine ID in response to a WTSSBX_GetMostSuitableServer method call, we can override the default SB load balancing logic and provide our own.
In the next blog post, I will provide some design guidelines on how to construct your plug-in as well as an example of a plug-in that does resource-based load balancing.
Awesome!! I will be waiting for your next post.
196 Microsoft Team blogs searched, 97 blogs have new articles in the past 7 days. 218 new articles found...
Like many features of Windows Server, the TS Session Broker is a "platform" feature that provides basic functionality, but Microsoft wrote it in such a way that it's highly extensible. To that end, the Microsoft Terminal Server team has
I've been looking for a way to redirect users to different terminal servers based on their group membership in active directory. The only way I have found is to implement a session broker plugin (is there an easier way?). I have never developed a COM-object before, and unfortunately it was harder to get this thing to work than I had hoped..
This is what I get in tssdis.log when i start the session broker service:
1604: 1:36:14 AM INFO: Session Broker plugin is registered
1604: 1:36:14 AM INFO: Loading plug-in
1604: 1:36:14 AM ERROR: CoCreateInstance failed with error code hr = 0x80040154
Error 0x80040154 means "Class not registered". I seem to get this error no matter what I try.
I tried to make a basic COM server that implements the IWTSSBPlugin interface in Visual C++. I also made a client that calls cocreateinstance and instanciates it without error using the interface ID for IWTSSBPlugin. So why does it say "class not registered" from the session broker service?
I have given NETWORK SERVICE local access, local activation and local launch permissions in the COM security default settings in dcomcnfg.exe. I have also given NETWORK SERVICE access and launch permissions for my COM server with OLE/COM viewer.
Under the HKCR\CLSID\<CLSID>\ key in the registry I have:
(Default) = <name>
InProcServer32\(Default) = <path to dll>
InProcServer32\ThreadingModel = "Both"
I have tried som other settings as well, but as I understand it, this is all that is needed. Does session broker require something else in the registry? It could be something with my COM server implementation, but the error indicates that something is wrong in the registry..
I also tried to make a CLR based COM server in C# and registered using regasm. The class is clearly registered in the registry, but still the same error from session broker.
Is there anything wrong with using a CLR based COM server? Does runtime version matter?
I'm waiting for the example code!
I did C++ Session Broker Plugin and it works fine.
to David - you still have problem with your plugin?
I have looked in msdn about Win32_SessionDirectorySession class (its description is in the file
%systemroot%\system32\wbem\tssdwmi.mof file) in Windows Server 2008 DataCenter.
When I am using WMI query: SELECT * FROM Win32_SessionDirectorySession
I receive error: "80041024 Provider is not capable of the attempted operation."
In the same time queries to such classes as Win32_SessionDirectoryCluster and Win32_SessionDirectoryServer
are executing fine.
But there are some differences of the (Win32_SessionDirectoryCluster, Win32_SessionDirectoryServer) and Win32_SessionDirectorySession interface in the file tssdwmi.mof.
Maybe I need to install smth for working of Win32_SessionDirectorySession class?
TS Session Broker is installed and works with queries on the classes Win32_SessionDirectoryCluster and Win32_SessionDirectoryServer.
Have you any ideas about that?
Any help would be appreciated!
Does anyone have any sample code that they would be willing to share? (C++).
I am also having the following error :
2000: 17:29:07 PM INFO: Session Broker plugin is registered
2000: 17:29:07 PM INFO: Loading plug-in
2000: 17:29:07 PM ERROR: CoCreateInstance failed with error code hr = 0x80040154
2000: 17:29:07 PM DISJetRecover() begin
2000: 17:29:07 PM We have 0 Servers to recover
2000: 17:29:07 PM g_RepopulateSession is set to TRUE
2000: 17:29:07 PM DeleteJetFiles() begin...
2000: 17:29:07 PM DeleteJetFiles() ended...
4180: 17:29:09 PM DISOpenServer() begin...
4180: 17:29:09 PM DISOpenServer() end...
2000: 17:29:09 PM Session Broker Active
2000: 17:30:53 PM Session Broker Stopped
2000: 17:30:53 PM INFO: Calling UnloadExtensibilityPlugin ...
2000: 17:30:53 PM INFO: Plugin is totally unloaded
Can you guys help?
I have also Problems with the Com Addin.
Have someone a sample code ?
We've released a later version of the broker since this blog post was published and recommend using that platform. Sample code for filter plugins and resource plugins for the RD Connection Broker in WS08 R2 is available from the Downloads section here: archive.msdn.microsoft.com/rdsdev
Hope this helps,