Try this out:
1) Create a new blank solution
2) Add 3 projects: 1 console app called 'Service', 1 console app called 'Client', 1 class library called 'Library'
3) Add references to System.Runtime.Remoting in Service and Client project
4) Add reference to Library in Service and Client project
5) In the Library project add 2 interfaces: ISAO and ICAO. Code for these 2 interfaces are:
using System;
namespace Library
{
public interface ICAO
{
void CallCAO();
}
}
using System;
namespace Library
{
public interface ISAO
{
int AmountOfClients { get; }
void RegisterCAO(ICAO cao);
}
}
6) In the Client project, Add 2 files: CAO.cs and app.config
using System;
using Library;
namespace Client
{
public class CAO : MarshalByRefObject, ICAO
{
public void CallCAO()
{
Console.WriteLine("Notifying CAO");
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<client url="tcp://localhost:9000">
<activated type="Library.CAO, Library" />
<wellknown type="Library.ISAO, Library" url="tcp://localhost:9000/SAO.rem" />
</client>
<channels>
<channel ref="tcp" port="0" >
<clientProviders>
<formatter ref="binary"/>
</clientProviders>
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
7) Alter the Program.cs from the Client project
using System;
using System.Runtime.Remoting;
using Library;
namespace Client
{
class Program
{
static void Main(string[] args)
{
RemotingConfiguration.Configure("Client.exe.config", false);
Console.WriteLine("This is the client\r\n");
System.Threading.Thread.Sleep(500);
ISAO sao = (ISAO)Activator.GetObject(typeof(ISAO), "tcp://localhost:9000/SAO.rem");
CAO cao = new CAO();
sao.RegisterCAO(cao);
Console.WriteLine("CAO has been added to SAO\r\n");
Console.ReadLine();
}
}
}
8) In the SERVICE project, add 2 files: SAO.cs and app.config
using System;
using System.Collections.Generic;
using System.Text;
using Library;
namespace Service
{
public class SAO : MarshalByRefObject, ISAO
{
private List<ICAO> _clients;
public int AmountOfClients { get { return _clients.Count; } }
public SAO()
{
_clients = new List<ICAO>();
}
public void RegisterCAO(ICAO cao)
{
_clients.Add(cao);
}
public void NotifySAO()
{
Console.WriteLine("Notifying SAO");
}
public void NotifyCAO()
{
foreach (ICAO cao in _clients)
cao.CallCAO();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<activated type="Library.ICAO, Library" />
<wellknown mode="Singleton" type="Service.SAO, Library" objectUri="SAO.rem" />
</service>
<channels>
<channel ref="tcp" port="9000" >
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
9) In the Service project, alter the Program.cs
using System;
using System.Runtime.Remoting;
using Library;
namespace Service
{
class Program
{
static void Main(string[] args)
{
RemotingConfiguration.Configure("Service.exe.config", false);
Console.WriteLine("This is the service\r\n");
SAO sao = new SAO();
RemotingServices.Marshal(sao, "SAO.rem", typeof(SAO));
Console.WriteLine("There are " + sao.AmountOfClients + " clients registered.");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("There are " + sao.AmountOfClients + " clients registered.\r\n");
// Notice where the string 'Notifying SAO' pops up
sao.NotifySAO();
// Notice where the string 'Notifying CAO' pops up
sao.NotifyCAO();
Console.ReadLine();
}
}
}
10) Now right click solution -properties -check Multiple start-up projects
11) Set 'Start' for Client and Service
12) Run the program
13) Notice that, even though the SERVICE calls sao.NotifyCAO(); theactual Console.WriteLineis executed on the CLIENT window !
Et voila, you just created service-to-client communication.
Hope this helps,
Stefan