Peer Channel and MessagePropagationFilter

If you have been playing with Peer Channel, you probably noticed that there is a programmability element called PeerNode. In this blog post, I would like to briefly discuss one of the properties on this object called - "MessagePropagationFilter". you can use this filter to affect the message flow inside a Peer Channel mesh.

There is a single abstract method in the abstract class System.ServiceModel.PeerMessagePropagationFilter:

public abstract PeerMessagePropagation ShouldPropagateMessage(Message message, PeerMessageOrigination origination);

to participate in the message flow, you simply create a concrete derived class of PeerMessagePropagationFilter and attach it to the peernode.

Make sure you attach your propagation filter before opening the peer channel.

For evey message that passes through your peernode (basically, the transport manager created under the covers to support your peer channel instance), this filter is invoked to make propagation decisions. This is true for messages that originated elsewhere in the mesh and your node has received as well as messages created by your application. the last argument to the method call identifies the origin (PeerMessageOrigination.Local or PeerMessageOrigination.Remote). For each message, your filter can decide if the message should be delivered only locally, meaning to other endpoints in your application, onto the mesh only, both or simply drop the message. You can do this, by returning one of the intuitively named constants in the PeerMessagePropagation enum: None, Local, Remote, LocalAndRemote.

A full copy of the message is passed to this method, any changes you make to the message, do not affect the actual message.

just for fun, here is a sample implementation that only delivers remote messages to your application (filters out locally generated messages).

class  RemoteOnlyMessagePropagationFilter : PeerMessagePropagationFilter

{

public RemoteOnlyMessagePropagationFilter()

{

}

public override PeerMessagePropagation ShouldPropagateMessage(Message message, PeerMessageOrigination origination)

{

PeerMessagePropagation destination = PeerMessagePropagation.LocalAndRemote;

    if(origination == PeerMessageOrigination.Local)

       destination = PeerMessagePropagation.Remote;

    return destination;

}

}

 

here is the code snippet to attach an instance of the filter class to your peer node:

      

ChannelFactory<IDoNothing> channelFactory = new ChannelFactory<IDoNothing>(...);

IDoNothing doer = channelFactory.CreateChannel();

RemoteOnlyMessagePropagationFilter myPropagationFilter = new RemoteOnlyMessagePropagationFilter();

**

PeerNode myPeerNode = ((IClientChannel)doer).GetProperty<PeerNode>();

myPeerNode.MessagePropagationFilter = myPropagationFilter;

doer.Open();

make sure to attach the filter before you open the channel.

This technique can be useful if you do not want to receive messages that your application has generated - can happen if you have an output channel and a service endpoint both opened at the same endpoint address. Or, if you opened a duplex channel - Peer Channel's duplex channel instances reflect the message back to your instance context.

as you can see this is a very simple example. you are not gauranteed that the filter invokaction by the node is serialized. Multiple threads may call into your filter at the same time - unless you opened your peer channel instance on a UI thread.

Comments

  • Anonymous
    August 27, 2006
    Is there a size limit for messages on PeerChannel? I have tried to set the maxReceivedMessageSize for the binding. I have a simple chat client - similar to Kevin Ransom's example. But, if the text size exceeds a certain length, message is not sent to the peers. Changing the maxReceivedMessageSize seems to have no effect on the size of the message I can send. I am using the July CTP version.

  • Anonymous
    September 18, 2006
    The comment has been removed

  • Anonymous
    October 01, 2006
    Hi Madhu,

    Just added the first in a series of PeerChannel tech tips- please take a look at this post and see if it helps.

  • Anonymous
    October 29, 2006
    there two things confused me, please help: 1: RemoteOnlyMessagePropagationFilter, is this a member function or something else? cann't compile. 2: channelFactory.GetProperty<PeerNode>(), I got a "null" value, why? I run two same applications on one machine the same time, withou MessagePropagationFilter, verything ok, but message wouldn't be filtered. thank you!

  • Anonymous
    January 08, 2007
    Hi dragonpoint, Good catch..

  1. RemoteOnlyMessagePropagationFilter looks like a cut-paste error :)- it's meant to be a constructor for your alternateMessagePropagationFilter - so the code would work if you match the class name and the constructor name to say RemoteOnlyMessagePropagationFilter.
  2. You can try retrieving the PeerNode associated with the channel factory through the channel as well - Here's how: ChannelFactory<IDoNothing> channelFactory = new ChannelFactory<IDoNothing>(...); channelFactory.Open(): IDoNothingDoer doer = factory.CreateChannel(); PeerNode myPeerNode = ((IClientChannel)doer).GetProperty<PeerNode>(); RemoteOnlyMessagePropagationFilter myPropagationFilter = new RemoteOnlyMessagePropagationFilter(); myPeerNode.MessagePropagationFilter = myPropagationFilter; doer.Open(); Hope this helps! Thanks, Shalini. --SDET (MSFT)
  • Anonymous
    January 10, 2007
    Peerchan:  thank you! I've done that :)