Calling a Windows Service from ASP.NET via Remoting & IpcChannel
I recently had to design a Windows Service that connects to several game servers via UDP, gathers stats, and then updates a MSSQL database.
These stats were then made available in real-time on a web-site written in C# and ASP.NET.
Before Remoting
For the first version of the application, the web-site and Windows Service were completely independent. The web-site would just query the database and determine, or make a best guess about what was going on inside the Windows Service at that exact time. This worked pretty good, and although the database is now about 1GB in size and growing fast, I optimized it good enough for this to work in real-time without a hitch.
There was some caching going on, thanks to the OutputCache directive in ASP.NET, but surprisingly enough there were no performance issues.
After Remoting
All right, so because I needed to display some extra information about ‘online’ users, that the Windows Service knew about, but the database didn’t, I decided to have a look at .NET Remoting. This was my first time working with it.
These were the issues I experienced (as a Remoting newbie) when rewriting the Windows Service to be accessible via .NET Remoting:
- The actual functionality of the Windows Service had to be moved to a separate Class Library (.DLL).
If you wrote your Windows Service all in one .EXE you will have to move it out to DLLs. Ideally you would have a DLL for the actual functionality – let’s call this Business.dll -, and another DLL for the Remoting methods and objects – Remoting.dll. You then create wrapper methods and objects in Remoting.dll which delegate work to Business.dll.The reason you have to do this is that the ASP.NET web-site will need to know which methods and objects are available via Remoting, and how to access them. All you have to do now is add a reference to Remoting.dll inside the ASP.NET web-site.
This would have actually been a good design decision in the first place, because the Firewall on the server that was running the Windows Service kept complaining about changes to the Service’s .EXE each time I updated and restarted it. After moving the code out to a DLL, the complaints stopped because the .EXE was just a wrapper and it wasn’t changed any more.
- The Remoting Wrapper.
Now you can create wrapper methods around Business.dll in the Remoting.dll Class Library. To enable remoting, you will need to create a class that inherits from MarshalByRefObject . I’ll supply a code sample for clarity:This is actual code from a real application, but it should help you get started.
- Using IpcChannel for Remoting.
Because the Windows Service and Web Site were hosted on the same computer, I decided that the best Remoting channel to use is IpcChannel (Inter-Process Communication channel via Named Pipes). The alternatives are TcpChannel and HttpChannel, which I would recommend for situations where the service and web site are not on the same computer.The problem with IpcChannel is that it requires both the Windows User Account that is running the Windows Service, and the User Account that is running ASP.NET to be under the same User Group, otherwise you will get the following error:
If you have complete control over the system and are certain that no other applications can interact with your service, you can work around this security measure by allowing users in the “Everyone” Group to access the IpcChannel. Here’s how to do it:
RemotingException: Failed to connect to an IPC Port: Access is denied.
Notice the exclusiveAddressUse property. I needed to add this due to intermittent problems which occured when the service crashed during debugging, and the Remoting channel didn’t get properly closed.
- Connecting to the Service from ASP.NET
In order to connect to the service in ASP.NET via Remoting you will have to create an .XML file with the following contents (this can also go in your Web.config if you want):All you have to do now is let the Remoting class know about your configuration file and you can start using it! It’s as easy as:
// now just instantiate your remote class FragRankRemoting r = new FragRankRemoting(); // and you can use it just like any other class, even if it is hosted remotely ListplayersAll = r.GetOnlinePlayers();
That’s it, the Windows Service and ASP.NET web-site are now communicating through Named Pipes.
[tags]Windows Service, Remoting, .NET, C#, IpcChannel, Named Pipes, ASP.NET, IPC[/tags]
Bookmark on del.icio.us
on October 2nd, 2007 at 7:25 am
Hello Andrei, thats great example how to solve my problem in my project..
Thanks for it. Havent impelemted it, i’ll send mail if i’ve got trouble on it.
Regards m8.
on October 2nd, 2007 at 7:31 am
Glad I could help. Let me know if you need anything else.
on October 4th, 2007 at 7:27 am
Hey!
Thanks a lot man. This made my day. I was wondering where one can look up these attributes that can be sent to the various channels? Once again, thanks
on June 18th, 2008 at 1:45 pm
Thanks for the read. I was having a bit of issues implementing this at first on my server. I had to call my support guys at Server Intellect to get it running right on my server. Thanks man!
on April 7th, 2009 at 9:05 am
Perfect article thanks, I am looking for consuming Remoting Events in an asp.net web page. I am writing a web application to monitor windows service, the service registers a Remoting Object which raise events about the service status, I need to consume these events in a web page, I did wrote a windows application sample and everything works just fine, but in web things different, I just don’t want to go to pulling the status by calling methods from the Remoting Object, which the only solution I have rightnow. any ideas?
Thanks in advanced,
Anas.
on April 7th, 2009 at 5:30 pm
Thank’s a lot …. is great solution … !!!
on November 15th, 2009 at 12:10 pm
I thank you sir. Sorted my problem out 1st time. I only wish I hadn’t wasted so much time on MSDN.
on January 28th, 2010 at 9:35 am
Hi sir,
Thanks for your article.
I am a beginner level programmer in asp.net ..
I recently face issues that access windows service via asp.net..i red your article ..but i cant get your points..
actually in my application for access windows service,
i use it below code..but it does not work(socketexception occur)
my code behind is,
Dim URL As String
URL = System.Configuration.ConfigurationSettings.AppSettings("URL") & "Monitorobj.Rem"
Objmonitor = Activator.GetObject(GetType(ClassLibrary1.monitor), URL)
and in my web.config is,
but i dont have any brief knowledge about windows service..
i expect your valuable suggestion..please reply me.
on May 12th, 2010 at 9:50 am
Can I start or stop a windows service using asp.net or using a web page ?
on July 24th, 2010 at 12:32 pm
Great article! Exactly what I was looking for, has everything I needed in one page. Thanks!