Using DssEnvironment class inside a DssService
-
vendredi 24 février 2012 00:10Modérateur
Hi All,
I would like to create a forwarding port from a non-DssService class (a simple C# class) using the DssEnvironment.ServiceForwarder method. This simple C# class is referred by a DssService class.
Since, the DssService will be hosted by DssHost.exe, I assumed that the DssEnvironment.Initalize method would have been automatically called by DssHost.exe (just like we have to manually call DssEnvironment.Initalize for external hosting) and hence I thought I can use the DssEnvironment.ServiceForwarder method to create forwarding ports. However, when I tried to use the DssEnvironment.ServiceForwarder, it threw me an "DSS Environment must first be initialized" error.
Can you please help me out with this.
Thanks,
Venkat
Toutes les réponses
-
dimanche 11 mars 2012 08:26Modérateur
Hi All,
I was wondering if anyone had an opportunity to look at this.
Thanks,
Venkat
-
mercredi 14 mars 2012 23:39Modérateur
Hi,
Can you explain how your C# class is initially loaded? If it is loaded by an existing service, you don't have to call DssEnvironment.Initialize. However if your exe is not DssHost/DssHost32, then you will have to call Initialize.
Nick.
-
dimanche 18 mars 2012 23:23Modérateur
Hi Nick,
Thanks for your time and reply. It is loaded by an existing service and still I am getting an error. I was expecting that the DssEnvironment.Initialize will be called by the service.
Thanks,
Venkat
-
jeudi 22 mars 2012 00:40Propriétaire
Venkat,
Could you provide a short code example of what you are doing? From the description it seems that it should work.
-
jeudi 22 mars 2012 22:10Modérateur
Hi Gershon Parent,
Thanks for your time and reply. Please find below the function I am trying to call from a DSS Service. The DssHelper class below is built as a separate dll ("DssHelper.dll")
namespace Cbda.DssHelper
{public static class DssHelper { public static PortSet<dssp.CreateResponse, Fault> CreateService(string hostname, int port, string serviceIdentifier, int timeOutMilliseconds) { UriBuilder builder = new UriBuilder("dssp.tcp", hostname, port, "constructor"); cs.ConstructorPort constructorPort = DssEnvironment.ServiceForwarder<cs.ConstructorPort>( builder.Uri); dssp.ServiceInfoType serviceInfo = new dssp.ServiceInfoType(serviceIdentifier, null); cs.Create createService = new cs.Create(serviceInfo); createService.TimeSpan = TimeSpan.FromMilliseconds(timeOutMilliseconds); constructorPort.Post(createService); return createService.ResponsePort; } }
}
I create a new DSS Service, add a reference to the "DssHelper.dll" and do the following.
var responsePort = DssHelper.CreateService("localhost", 40001, "MyServiceUri", 2000);I host this DSS Service using DssHost on http port 50000 and tcp port 50001. The above method call to CreateService is intended to start another service on tcp port 40001 (assume that another DssHost is running on tcp port 40001) . However, when I execute the CreateService method, it gives an error when making the DssEnvironment.ServiceForwarder call. The error I get is "DSS Environment must first be initialized". I was expecting that the DssEnvironment.Initialize method would have been called with (50000, 50001) by the framework when my service started (just like we do it manually for external hosting) and I can use the methods in the DssEnvironment class in a DSS service just like I do for external hosting.
Thanks,
Venkat
-
vendredi 30 mars 2012 01:33Propriétaire
A developer here has suggested "There is a method on DsspServiceBase that does the same thing, called "ServiceForwarder" Can he get that to work?"
-
samedi 31 mars 2012 00:06Modérateur
Hi Gershon Parent,
Thanks for the information and time. I have used the ServiceForwarder method given in http://msdn.microsoft.com/en-us/library/bb660305.aspx. This method can be used only in DSS service class that derive from DsspServiceBase. However my class DssHelper is not a DSS service class but is used by a DSS Service class. I do not want to introduce any dependency (either dll or type) from the DssHelper class to the DSS Service class. Just like external hosting, I was wondering if DsspServiceBase (or any of its base classes) uses the DssEnvironment class internally for doing operations like creating services, partnering with services, logging messages, creating forwarding ports and scheduling tasks. If this were the case then I can use the methods of the DssEnvironment class from any class like my DssHelper that is not a DSS Service but is used by a DSS service.Thanks,
Venkat
-
mercredi 11 avril 2012 21:24Modérateur
The easiest way to “piggyback” on an existing, already initialized, DssEnvironment is going to be to inherit DsspServiceBase. Maybe have your own base with helpers methods included or at least helpers that handle the “glue” and call out to a more pure set of utility functions. I would suggest doing that even though, as you say, that introduces dependencies you’d rather avoid. DSS seems to be a bit “infectious” in that sense J
As for the error message (“DSS Environment must first be initialized”), I’m guessing that your DssHelper is being called before the node has initialized. One (not so pretty) way I’ve seen to determine whether init has happened is to check for the TaskQueue having been created (DssEnvironment.TaskQueue != null).
- Proposé comme réponse Ashley Nathan FenielloMicrosoft Employee, Moderator mercredi 11 avril 2012 21:24
-
mercredi 11 avril 2012 21:45ModérateurThanks Ashley Feniello for your time and clarification. I understand that the DsspServiceBase internally initializes the DssEnvironment. Does this mean that the DsspServiceBase calls the DssEnvironement.Initialize method internally? If that seems to be the case then whatever I am trying to do should work. This is because DssEnvironement is a static class and all the helper methods (this includes the ServiceForwarder method) of the class can be used in my DssHelper class which does not derive from DsspServiceBase but is used by a class that derives from DsspServiceBase and that class would have called DssEnvironement.Initialize. So, the error message (“DSS Environment must first be initialized”) should not occur.
-
vendredi 13 avril 2012 00:59Modérateur
DssNode calls DssEnvironment.Initialize() during its own initialization. It could be that something else is wrong and even that isn’t happening.
I believe it’s more likely that it’s due to the fact that internally DssEnvironment.Initialize() is async (something like ThreadPool.QueueUserWorkItem(_ => DoInitialize(…))) and hasn’t completed by the time you’re being called.
To rule this out, do you think you could try something silly like the following in your DssHelper?
while (DssEnvironment.TaskQueue == null) { Thread.Sleep(50); }
-
lundi 16 avril 2012 21:24ModérateurThanks Ashley Feniello for your time and suggestion. I tried to do whatever you said and I get the exception "DSS Enviroment not started" when I try and use the DssEnvironment.TaskQueue in either my service class or in the class that my service class uses.
-
mercredi 18 avril 2012 21:11Modérateur
Hi Venkat,
I've tried to do this in the past and spoken with the architects of DSS about this problem. It turns out that it is very difficult to write a DSS Client that is not a DSS Node. If you managed to pull it off, you would find there were runtime binary dependency issues with your solution.
The approach that was suggested to me at the time was to communicate with DSS using HTTP REST instead. However the level of knowledge and effort needed to pull this off exceeded my ability & resources. I'd suggest that you not try to go down this path, but instead spin up a new DSS Node/Service if you wish to talk to a DSS Service.
There was discussion about extending DSS to make this scenario easier. Unfortunately this feature has not been implemented so our suggested direction remains to only communicate to a DSS Node from another DSS Node.
- jcb
- Proposé comme réponse Harshavardhana Kikkeri [MSFT]Microsoft Employee, Moderator mardi 1 mai 2012 22:17
- Marqué comme réponse Harshavardhana Kikkeri [MSFT]Microsoft Employee, Moderator samedi 5 mai 2012 00:30

