tags:

views:

486

answers:

1

I wrote some code for a WCF P2P chat program.

<services>
  <service name="PeerChat.Form1">
    <host>
      <baseAddresses>
        <add baseAddress="net.p2p://PeerChat/" />
      </baseAddresses>
    </host>
    <endpoint name="PeerChatEndPoint" address="" binding="netPeerTcpBinding" bindingConfiguration="BindingUnsecure"
       contract="PeerChat.IChatService" />
  </service>
</services>
<bindings>
  <netPeerTcpBinding>
    <binding name="BindingUnsecure">
      <resolver mode="Pnrp" />
      <security mode="None" />
    </binding>
  </netPeerTcpBinding>
</bindings>
<client>
  <endpoint
      name="PeerChatClientEndPoint"
      address="net.p2p://PeerChat/"
      binding="netPeerTcpBinding"
      bindingConfiguration="BindingUnsecure"
      contract="PeerChat.IChatService"
  />
</client>

I then host the service as follows:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public partial class Form1 : Form, IChatService
{

    IChatService channel;
    ServiceHost host = null;
    ChannelFactory<IChatService> channelFactory = null;

    private void StartService()
    {
        //Instantiate new ServiceHost
        host = new ServiceHost(this);
        //Open ServiceHost
        host.Open();
        //Create a ChannelFactory and load the configuration setting
        channelFactory = new ChannelFactory<IChatService>("PeerChatClientEndPoint");
        channel = channelFactory.CreateChannel();
        //Lets others know that someone new has joined
        channel.SendMessage("Hello."+ Environment.NewLine);

        foreach (var cloud in Cloud.GetAvailableClouds())
        {
            textBox2.Text += cloud.Name + Environment.NewLine;
        }
    }
    private void StopService()
    {
        if (host != null)
        {
            channel.SendMessage("Bye." + Environment.NewLine);
            if (host.State != CommunicationState.Closed)
            {
                channelFactory.Close();
                host.Close();
            }
        }
    }

The problem is I can send a message to the same instance of the program but not to another instance. Ie an instance only receives its own messages not messages from other instances. Not sure if it is a matter of configuring PNRP correctly? I tested on Windows 7.

+1  A: 

You wouldn't happen to have both instances of the program listening to the same end point would you? I am not certain, but I suspect what may be happening is that your client application is registering itself on the endpoint first, then intercepting all the messages that come to that endpoint before the second one can get them. What I'd suggest trying to do is configuring the second instance to start up on an endpoint with a diferent Uri. So say one connects on net.p2p://PeerChatA/ and the other net.p2p://PeerChatB/ .

Streklin
But i thought the whole point of listening on the same mesh address is to get the messages sent to that mesh?
Ries
That is true, but that assumes that the two programs are running in two different places - so one is listening on that address on machine A and the other on machine B. I haven't seen anything on WCF which defines the behavior when two apps are sending and receiving on the same end points on the same machine and *I* suspect the WCF system might be having trouble with that test case in your situation - hence the suggestion.
Streklin
But then why will both instances receive its own messages?
Ries
Possibly a first come first situation? I don't know enough about the messaging system in WCF to explain that - all I can suggest is that WCF doesn't seem to be designed with the expectation that people will do what you're doing - hence the behavior is likely undefined. If my suggestion worked on your local machine, I'd recommend posting a question about that the definition of the behaviors of using the same endpoints on the same machine with the same program - I am sure there is someone that has more in depth knowledge that can explain it should this turn out to be the case.
Streklin