
Remoting Server-Side
Originally published on my old blog at cumps.be on April 3, 2005.
When the Windows Service was successfully running, a way had to be found to control it. There was a ServiceController class which allowed controlling a service and sending messages to it through the ExecuteCommand method. This method was limited to sending integers without getting anything back. A better solution was to use Remoting to control the service.
Remoting allows for interprocess communication, making objects available between different processes. An object is passed from server to client by reference, where the client can work with it as if it were a local object at the client. Remoting takes care of collecting information about the client calls and sending it to the server, where it is passed to the server object which performs the action on the client’s behalf. The result of this operation is then sent back to the client.
Remoting can transport this information over different channels, such as TCP and HTTP for example. In the project, a TCP channel was used, with the following code:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace MediaService.Player {
public class PlayerService : System.ServiceProcess.ServiceBase {
private TcpChannel tcpChannel;
private void SetupRemoting() {
this.tcpChannel = new TcpChannel(this.configData.RemotingPort);
ChannelServices.RegisterChannel(this.tcpChannel);
RemotingConfiguration.ApplicationName = "MediaServicePlayer";
After a channel had been set up, there were different possibilities to make a certain object available. But first, the object had to be created. This was a simple class, which inherited from MarshalByRefObject, and implemented a custom interface.
using System;
namespace MediaService.Player {
public class PlayerServiceController: MarshalByRefObject,
IPlayerServiceController {
The interface was used to make it possible to give consumers of the remote object only the assembly with the interface, instead of the implementation.
After an object was created, it was possible to register this type as a WellKnownType. There were two possibilities for this. It could be registered as a Singleton, which would make sure only one instance of the object lived on the server at a given time. The other possibility was to register it as SingleCall, which would create a new object for each call. Neither proved successful, because both were unable to call methods on the service. The solution was to instantiate a new object when the service started, and to make this instance remotely available. This allowed the object to be in contact with the Windows Service, making it possible to control it. The following code published the object on tcp://host:port/MediaServicePlayerController:
RemotingServices.Marshal(this.playerController,
"MediaServicePlayerController");
At the end, when the service was stopped, everything had to be cleaned up. The published object got disconnected and the channel got unregistered.
private void TearDownRemoting() {
RemotingServices.Disconnect(this.playerController);
ChannelServices.UnregisterChannel(this.tcpChannel);
} /* TearDownRemoting */
The client side shows how the web service uses this object.
You May Also Like

Boxing/Unboxing in .NET
Boxing and unboxing in .NET: what happens on the stack and the heap, and why the overhead hurts heavy code like path finding.

Remoting Client-Side
The consumer side of .NET Remoting: an ASP.NET web service that gets the controller object from a Windows Service on the same machine.

Windows Services
Windows Services, how they differ from the usual Windows Forms approach for business applications, and how I built one.



