This sample demonstrates using the NetEventRelayBinding binding on the Windows Azure platform AppFabric Service Bus. This binding allows multiple applications to listen to events sent to an endpoint; events sent to that endpoint are received by all applications.

The application accepts one of three mutually exclusive, optional command line parameters that select the connectivity mode for the Service Bus environment.

Prerequisites

If you haven't already done so, read the release notes document that explains how to sign up for a Windows Azure platform AppFabric account and how to configure your environment. It also contains important information about the default security settings for your environment that you need to be aware of.

Service Contract & Implementation

In this sample, the project defines the IMulticastContract and MulticastService implementation. Hello and Bye are used within the application to notify participants when a user joins and leaves the chat. Chat is called by the application when a user provides a string to contribute to the conversation.

Note that the methods must be marked as IsOneWay=True.

C# 
[ServiceContract(Name = "IMulticastContract", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
public interface IMulticastContract
{
     [OperationContract(IsOneWay=true)]
     void Hello(string nickName);
 
     [OperationContract(IsOneWay = true)]
     void Chat(string nickName, string text);
 
     [OperationContract(IsOneWay = true)]
     void Bye(string nickName);
}
Visual Basic 
<ServiceContract(Name := "IMulticastContract", Namespace := "http://samples.microsoft.com/ServiceModel/Relay/")> _
Public Interface IMulticastContract
    <OperationContract(IsOneWay:=True)> _
    Sub Hello(ByVal nickName As String)

    <OperationContract(IsOneWay := True)> _
    Sub Chat(ByVal nickName As String, ByVal text As String)

    <OperationContract(IsOneWay := True)> _
    Sub Bye(ByVal nickName As String)
End Interface

The service implementation is shown below.

C# 
ServiceBehavior(Name = "MulticastService", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
class MulticastService : IMulticastContract
{
    void IMulticastContract.Hello(string nickName)
    {
        Console.WriteLine("[" + nickName + "] joins");
    }
 
    void IMulticastContract.Chat(string nickName, string text)
    {
        Console.WriteLine("[" + nickName + "] says: " + text);
    }
 
    void IMulticastContract.Bye(string nickName)
    {
        Console.WriteLine("[" + nickName + "] leaves");
    }   
}
Visual Basic 
<ServiceBehavior(Name := "MulticastService", Namespace := "http://samples.microsoft.com/ServiceModel/Relay/")> _
Friend Class MulticastService
    Implements IMulticastContract
    Private Sub Hello(ByVal nickName As String) Implements IMulticastContract.Hello
        Console.WriteLine("[" & nickName & "] joins")
    End Sub

    Private Sub Chat(ByVal nickName As String, ByVal text As String) Implements IMulticastContract.Chat
        Console.WriteLine("[" & nickName & "] says: " & text)
    End Sub

    Private Sub Bye(ByVal nickName As String) Implements IMulticastContract.Bye
        Console.WriteLine("[" & nickName & "] leaves")
    End Sub

End Class

Configuration

The service and client endpoints use the NetEventRelayBinding binding.

Xml 
<netEventRelayBinding>
     <binding name="default" />
</netEventRelayBinding> 

The endpoints for the service and client are defined in the application configuration file. The client address is a placeholder that is replaced in the application. The following endpoints are defined:

Xml 
<service name="Microsoft.ServiceBus.Samples.MulticastService">
    <endpoint name="RelayEndpoint"
              contract="Microsoft.ServiceBus.Samples.IMulticastContract"
              binding="netEventRelayBinding"
              bindingConfiguration="default"
              address="" />
</service>
 
<client>
    <endpoint name="RelayEndpoint"
              contract="Microsoft.ServiceBus.Samples.IMulticastContract"
              binding="netTcpRelayBinding"
              bindingConfiguration="default"
              address="http://AddressToBeReplacedInCode/" />
</client>

Application

The application begins by obtaining the chat session name, the service namespace, and the issuer credentials. A chat nickname (a string used to identify the chatter) constructs the service URI using this information, then opens the service and the client channel to the Service Bus rendezvous endpoint for the chat session. The Hello method notifies all participating applications of the arrival of a new user. All strings are sent as messages to all participating applications until an empty string is provided as input. Finally, the Bye method notifies all participants of the departure of the client.

C# 
Console.Write("What do you want to call your chat session? ");
string session = Console.ReadLine();
Console.Write("Your Service Namespace: ");
string serviceNamespace = Console.ReadLine();
Console.Write("Your Issuer Name: ");
string issuerName = Console.ReadLine();
Console.Write("Your Issuer Secret: ");
string issuerSecret = Console.ReadLine();
Console.Write("Your Chat Nickname: ");
string chatNickname = Console.ReadLine();
TransportClientEndpointBehavior relayCredentials = new TransportClientEndpointBehavior();
relayCredentials.CredentialType = TransportClientCredentialType.SharedSecret;
relayCredentials.Credentials.SharedSecret.IssuerName = issuerName;
relayCredentials.Credentials.SharedSecret.IssuerSecret = issuerSecret;

Uri serviceAddress = ServiceBusEnvironment.CreateServiceUri("sb", "ChatRooms",
String.Format(CultureInfo.InvariantCulture, "{0}/MulticastService/", session));
ServiceHost host = new ServiceHost(typeof(MulticastService), serviceAddress);
host.Description.Endpoints[0].Behaviors.Add(relayCredentials);
host.Open();

ChannelFactory<IMulticastChannel> channelFactory = new ChannelFactory<IMulticastChannel>("RelayEndpoint", new EndpointAddress(serviceAddress));
channelFactory.Endpoint.Behaviors.Add(relayCredentials);
IMulticastChannel channel = channelFactory.CreateChannel();
channel.Open();

Console.WriteLine("\nPress [Enter] to exit\n");

channel.Hello(chatNickname);

string input = Console.ReadLine();
while (input != String.Empty)
{
   channel.Chat(chatNickname, input);
   input = Console.ReadLine();
}

channel.Bye(chatNickname);

channel.Close();sdp
channelFactory.Close();
host.Close();
Visual Basic 
Console.Write("What do you want to call your chat session? ")
Dim session As String = Console.ReadLine()
Console.Write("Your Service Namespace: ")
Dim serviceNamespace As String = Console.ReadLine()
Console.Write("Your Issuer Name: ")
Dim issuerName As String = Console.ReadLine()
Console.Write("Your Issuer Secret: ")
Dim issuerSecret As String = Console.ReadLine()
Console.Write("Your Chat Nickname: ")
Dim chatNickname As String = Console.ReadLine()

Dim relayCredentials As New TransportClientEndpointBehavior()
relayCredentials.CredentialType = TransportClientCredentialType.SharedSecret
relayCredentials.Credentials.SharedSecret.IssuerName = issuerName
relayCredentials.Credentials.SharedSecret.IssuerSecret = issuerSecret

Dim serviceAddress As Uri = ServiceBusEnvironment.CreateServiceUri("sb", "ChatRooms", String.Format(CultureInfo.InvariantCulture, "{0}/MulticastService/", session))
Dim host As New ServiceHost(GetType(MulticastService), serviceAddress)
host.Description.Endpoints(0).Behaviors.Add(relayCredentials)
host.Open()

Dim channelFactory As ChannelFactory(Of IMulticastChannel) = New ChannelFactory(Of IMulticastChannel)("RelayEndpoint", New EndpointAddress(serviceAddress))
channelFactory.Endpoint.Behaviors.Add(relayCredentials)
Dim channel As IMulticastChannel = channelFactory.CreateChannel()
channel.Open()

Console.WriteLine(Constants.vbLf & "Press [Enter] to exit" & Constants.vbLf)

channel.Hello(chatNickname)

Dim input As String = Console.ReadLine()
Do While input <> String.Empty
   channel.Chat(chatNickname, input)
   input = Console.ReadLine()
Loop

channel.Bye(chatNickname)

channel.Close()
channelFactory.Close()
host.Close()

Building and Running the Sample

After building the solution, perform the following steps to run the application:

  1. From a command prompt, run the application bin\Debug\MulticastSample.exe.

  2. From another command prompt, run the application \bin\Debug\MulticastSample.exe.

When finished, press ENTER to exit the application.

Expected Output – Application 1

What do you want to call your chat session? <chat-session>
Your Service Namespace: <service-namespace>
Your Issuer Name: owner
Your Issuer Secret: <issuer-secret>
Your Chat Nickname: <chat-nickname>

Press [Enter] to exit

hello
[jill] says: hello
[jack] says: hi, how are you?
[jack] says: who do you think will win the superbowl this year?

Expected Output – Application 2

What do you want to call your chat session? <chat-session>
Your Service Namespace: <service-namespace>
Your Issuer Name: owner
Your Issuer Secret: <issuer-secret>
Your Chat Nickname: <chat-nickname>

Press [Enter] to exit

[jill] says: hello
hi, how are you?
[jack] says: hi, how are you?
who do you think will win the superbowl this year?
[jack] says: who do you think will win the superbowl this year?



Did you find this information useful? Please send your suggestions and comments about the documentation.