apologies in advance for this question being dumb, or previously covered. I have researched far and wide but have not found any resources on WCF/ Windows Services that cover this question.
I have a managed Windows Service which is working nicely. Every n (>5) seconds it checks on the status (e.g. memory consumption) of some processes and other Windows services and also does some database logging and raises events where necessary.
I intend to make an ASP.NET website that would allow users to query the status of the processes that the Windows Service is monitoring. Having researched the options it looks like the up-to-date method would be to use a WCF Service, hosted in the Windows Service, to act as intermediary between the ASP.NET website and the Windows Service. Such that, a user could request through the browser a snapshot of the current status of whatever set of processes the Windows Service was monitoring, and have this request and subsequent response relayed through the WCF service (using named pipes, I think).
So, my difficulty is that there a set of methods and events in the Windows Service for which a single root object exists (let's say MonitorObject). I don't see how the ServiceHost can be instantiated with the reference to MonitorObject so that the WCF Service can call the methods in the Windows Service. I am thinking that perhaps I need to make the Monitor object a shared (I am VB'ing) member of the Windows Service class (that contains OnStart and OnStop) and make all the events shared so that the WCF Service can just access the WindowsService.SharedMonitorObject without needing to be passed the object....
However, I am lost in the subject and am seeking any advice on how best to proceed.
Thanks in advance.
I think you're going down the right track. I wouldn't necessarily make the entire MonitorObject shared, but you might put a shared method in that object that will return the single root object to the caller.
There is a design pattern called the Singleton Pattern that will help you with this. Jon Skeet has written an excellent article on some of the things to be aware of when using this pattern in .NET. His article uses C# for the examples, but here's a SO question referencing this pattern using VB.
While it's unclear from your description, my guess is that your Windows Service is essentially single-threaded right now. Just keep in mind that once you add the WCF service, you'll need to make the methods that it references thread-safe.
Related
I have a .net Web API 2 application that I need to use to call an web service (asmx) just to see if the web service is up and running correctly. I am a believer in architecture, so with that in mind I am not sure where to put the call to the web service. I found a post that suggested that I put this in the repository layer. Is this the correct location for that?
I would say its more of a personal preference + project specific; IMO you can place that web service in repository if it acts as a data-store or you could place it in business layer of the service does more of a business related stuffs.
But one thing I would do for sure is to create a wrapper/abstraction over this service before using it in any layer so that:
I can inject this dependency in the layers its being used
Unit testable code - DI and mockable
No changes in the layers where this is being consumed in case there is any change in service- for eg, asmx1 to asmx2 or change in asmx service to wcf or REST etc.
Not sure whether you will be able to find a specific answer to this, this is kinda arguable subject as opinions might differ according to personal preference
We currently have an .NET 4 application that consists of Windows Service running in the background and local or remote clients (only 1-3 normally).
The clients have a WPF GUI and need some data from the windows service. Therefore, we use WCF with NamedPipe binding for a local client and NetTcp binding for remote clients. This works, but we often have problems with endpoints that are not reachable (channel faulted or not found etc.). We already try to rebuild faulted connections but it seems to be pretty fragile...
Now enter Web Api: It looks like a HTTP based stack might be more robust (no channels, no endpoints, can be self-hosted in windows service as well). There seems to be no problems with broken channels because each request is handled individually. So if something fails, you just repeat the request. (And we have experience with ASP.NET MVC from other apps, so this not new to us).
Now we are thinking what might be our best bet. Is it better to "harden" our existing WCF service (one service interface with about 15 operations) or to move the interface to Web Api and run it as HTTP requests (with JSON data)? Performance is not our main issue here...
Any ideas?
Hartmut
I recommend you stick with WCF (SOAP) services for your WPF application rather than moving to the Web API. There are a number of reasons for this. First I think we need to consider what the new Web API is trying to address - namely to provide a framework for supporting RESTful/HTTP/hypermedia services. This is likely to be a good fit for building applications that make heavy use of HTTP such as web, mobile and JavaScript applications, where you want to maximise the "reach" or interopability of your services (irrespective of platform). This is not to say that you can't use it for WPF clients but in your case, where all traffic is local to your domain, it makes more sense to stick with your current implementation.
The binding choices you have made for your services / clients sound ok to me. I would focus on why your channels are faulting and address these issues. You may also want to consider hosting your services via IIS and use WAS to expose your non-HTTP endpoints. I have had much success with this in the past and for the most part has been pretty stable. It also takes away a few of the headaches with managing your own host. If you are concerned about the TCP binding faults, then just create a new HTTP or wsHTTP endpoint and use that instead. This will provide you exactly the same transport the web api uses without having to change your programming model.
I have some delphi code which, given a list of items, calculates the total price taking into account any special deals that might apply.
This code is non-trivial to rewrite in another language.
How should I set it up to communicate with a website running on the same server? The website will need to ask it for a price every time the user updates their shopping cart. It's possible that there will be multiple concurrent requests.
The delphi code needs to maintain an in-memory list of special deals, periodically refreshed from a database. So it cannot simply be executed every time or anything as simple as that.
I don't know what the website is written in, or even which http server it runs under, so I'm just looking for ideas or standard methods.
It sounds like the win32 app is already running as a Windows Service on the box. So, if you can't modify that service, you are going to have to deal with whatever way it wants to accept and respond to requests. This could be through sockets or some higher level communication protocol like web services.
You could do a couple of things. Write an assembly that knows how to communicate with the service and have your web site use that assembly. Or you could build a shim service that knows how to communicate with the legacy service, but exposes communication over higher level protocols such as web services. Either way will have the benefit of hiding the concurrency, threading and communications issue behind an easy to call interface, but the latter will make communicating with the service easier for everyone going forward.
If you can modify the delphi app to take an XML request and respond with an XML answer over a TCP socket (ideally using the HTTP protocol), you will be able to make it interoperate with most web server frameworks relatively easily. But the exact details of how to make that integration happen will depend on the language/framework it was written in.
If the web server is on windows you can compile your delphi app as a DLL that can return XML or HTML, taking parameters as part of the URL or a POST operation. Some details on making a Delphi DLL for web servers are here.
It doesn't matter what web server or OS the existing system is running under. What matters is what you want YOUR code to run under. If it is windows then the easiest solution would be to use WebBroker and write a custom ISAPI application, or use SOAP to expose web services. The first method could be used if you wanted to write a rest like API for instance, the second if your web application has the ability to consume web services.
Another option, if you are running both on the same box under IIS, is to create a COM/Automation object which you then invoke via server side scripting (ASP). If the application is an ASP.NET application, then I would use PRISM to port your code into an assembly.
I have done this with a quite complicated workers compensation calculator. I created a windows service using RemObjects Sdk. The calculations are exposed as a soap method so it can be accessed by nearly anything.
It's not necessary to use RemObjects in the service but it makes it much easier to do as it handles a lot of the underlying plumbing. The clients don't need RemObjects, they just need to be able to call soap methods. Nearly any programming langugae can do that.
You could also create an isapi dll for IIS that exposes a soap interface. This would be useful if other websites on different servers needed access to the methods. However I have handled this in my case by opening a port in the firewall to access my windows service.
There is a lot of examples on the web. A couple of places to start reading are About.Com and Dr Bob.
Torn this app into Windows Service. Write Web Service that will communicate with your windows service. You should spend some time designing your Web Service, because this Web Service is going to be your consistent interface, shielding old Delphi app. So in the future whenever you will want to write web app, mobile app, or whatever you will imagine, you will have one consistent interface – XML Web Service.
A popular way to integrate a web application with background services is a message broker.
The message flow would be:
the web application sends a "calculation request" message to a message destination on the message broker, which contains all needed parameters and also a correlation id to match the calculation request with the response from the Delphi service
one (or, in a high availability / load balanced environment more) Delphi services handle the messages: pull the next incoming message, process it by feeding the parameters to the calculation engine, and send a "calculation result message" back to the web server
the web server can either synchronously wait for the response (and discard responses which have no matching correlation ide) and build the result HTML document, or continue with other tasks and asynchronously receive the calculation result in a separate thread, for example in a Ajax based web application
See for an introduction this slideshow about the Dopplr image service:
http://de.slideshare.net/carsonified/dopplr-its-made-of-messages-matt-biddulph-presentation
If you can make it a service (but not a library), you have to do inter-process communication somehow - there are a few ways to do this on Windows:
Sockets directly which is hardest since you have to do marshalling/auth yourself
Shared Memory (yuck!)
RPC which works great but isn't trivial
DCOM which is easier but a pain to configure
WCF - but can you call it from your Windows Service written in Delphi?
I am using .Net 2.0 framework and would like to call a function in Windows service from a web service. Is this possible? And If yes, how much control I will have over the function i.e passing parameters, getting the result back etc. Any ideas would be greatly appreciated :)
Remoting is your best option if you need to pass parameter values.
If you don't need to share objects or anything too complex, ServiceController is probably easier.
You can do it through .NET remoting. If you go that route, it will appear you are calling a method and getting a result, but all your parameters will be serialized over the wire, and the result will be serialized back. Therefore, everything must be made serializable.
How about hosting a WCF service inside of the Windows Service. You can use net.tcp or named pipes to communicate between "your" web service and the one in the Windows Service. You can use the NetDataContractSerializer for serialization with type fidelity.
You could implement a basic http server that maps certain requests to functions. Query-string will be mapped to parameters. Actually not hard and I have done this in the past (as I provided some rudimentary template-based reporting). It wasn't dynamically, but it could be done dynamically. Look at HttpListener for a starting point. You could as well host the asp.net engine in it.
It has it advantages and disadvantages.
Why not package the function in its own DLL then distribute it with the Windows Service and the Web Service separately?
Create service project what export an interface COM or use PIPE to transfer data.
View this Interprocess Communication using Named Pipes in C#
I am just starting porting an application to ASP.net MVC and I have an object holding application state (it keeps track of certain processes running on the machine, starting and stopping as necessary and sending/receiving MSMQ message).
Where should I keep this object? In my current application (based on HttpListener) it is a singleton, however I know singletons make testing difficult. It would be difficult to mock or test this object, at least in the context of the MVC application itself, and it has it's own set of tests outside the application anyway. However it may need to be replaced by a stub for testing.
The object needs to be made available to a number of controllers. Where should I store this object and how should I make it available to the controllers? I've never seen a case like this described in any ASP.net MVC examples I've seen.
UPDATE:
I guess I need to explain why I can't store this data in a database. First I must explain what the application does:
The application serves images that are generated dynamically by a number of "engines", which are processes running on the server, communicated to via MSMQ. Lets call the object I'm asking the question about the EngineManager. The process goes something like this:
The client POSTs an XML request to the server, giving the name of "engine" to be used, as well as a number of parameters describing the image.
The application checks the EngineManager to see if that engine is running. If not, it starts it.
The application posts an MSMQ message to the engine and waits for the response.
The application sends the generated image back to the client.
If at any point the engine shuts down or crashes, the application must be aware of that so that it can be restarted on the next request to that engine.
When the application shuts down, all engines are also shut down.
There are several controllers that handle these requests, each doing a slightly different job. All of them need to communicate with the same EngineManager, as it also needs to, in certain situations synchronise access to other resources.
As you can see, it's not your typical database-backed webserver.
You should pass the object to the constructor of each Controller instance, and the controller action methods should all use the object instance passed in to the Controller instance constructor.
The default ControllerFactory which ships with ASP.NET MVC will not allow you to do this. However, there are free addon frameworks (the one I like is Autofac) which do permit this style of programming.
If you want this object to be available to all users, i.e. it is not session specific, you could look at storing it in application state:
http://msdn.microsoft.com/en-us/library/bf9xhdz4(VS.71).aspx
However, application state has several disadvantages, as listed on the page linked above, so make sure these issues don't affect you before you go down that route. In general I steer clear from Applciation state and store application data in a backend DB. As you don't want to go down this route application state may be OK for you.