Thursday, 29 March 2012

WCF P2P example

Create empty c# Console project and add reference to System.ServiceModel

Message interface and class

[ServiceContract(CallbackContract = typeof(IMessage))]
public interface IMessage
{
    [OperationContract(IsOneWay = true)]
    void Send(string sender, string message);
}
class MessageImpl : IMessage
{
    public string Name { get; set; }
    public MessageImpl(string name)
    {
        Name = name;
    }
    public void Send(string sender, string message)
    {
        if (!Name.Equals(sender))
        {
            Console.WriteLine("{0}: {1}", sender, message);
        }
    }
}

Messenger

public class Messenger
{
    public string Name { get; private set; }
    public IMessage Channel;
    public IMessage Host;
    private DuplexChannelFactory<IMessage> _factory;
    private readonly AutoResetEvent _stopped = new AutoResetEvent(false);
    private readonly AutoResetEvent _started = new AutoResetEvent(false);
    public Messenger(string name, AutoResetEvent started)
    {
        Name = name;
        _started = started;
    }
    private void StartService()
    {
        var binding = new NetPeerTcpBinding();
        binding.Security.Mode = SecurityMode.None;
        var endpoint = new ServiceEndpoint(
            ContractDescription.GetContract(typeof(IMessage)),
            binding,
            new EndpointAddress("net.p2p://Messenger"));
        Host = new MessageImpl(Name);
        _factory = new DuplexChannelFactory<IMessage>(
            new InstanceContext(Host),
            endpoint);
        var channel = _factory.CreateChannel();
        ((ICommunicationObject)channel).Open();
            
        Channel = channel;
    }
    private void StopService()
    {
        ((ICommunicationObject)Channel).Close();
        if (_factory != null)
            _factory.Close();
    }
    public void Start()
    {
        Console.WriteLine("Starting Messenger");
        StartService();
        Console.WriteLine("Running Messenger");
        _started.Set();
        _stopped.WaitOne();
        Console.WriteLine("Stopping Messenger");
        StopService();
        Console.WriteLine("Stopped");
    }
    public void Stop()
    {
        _stopped.Set();
    }
}

Main Program

class Program
{
    static void Main(string[] args)
    {           
        if(args.Length<1)
        {
            Console.WriteLine("usage: Messenger <your-name>");
            return;                
        }
        var me = args[0];
        var started = new AutoResetEvent(false);
        var messager = new Messenger(me,started);
        var thread = new Thread(messager.Start) { IsBackground = true };
        thread.Start();
        started.WaitOne();
        while (true)
        {                
            string tmp = Console.ReadLine();
            if (tmp == "bye") break;
            messager.Channel.Send(me, tmp);
        }
        messager.Stop();
        thread.Join();            
    }
}

To start it run

Messenger.exe <your-name>

To stop type ‘bye’

No comments:

Post a Comment