From last article Ad hoc Discovery .
When YallaTech discovered other chat instances all we knew about them was the Uri
of the service endpoint. So her chat window shows a chat with the host machine
name. besho,
on the other hand, knew that the chat message came from YallaTech because the chat
message included her name. In this article we will learn how we can extend
the metadata used in WS-Discovery to supply additional information (such as the
username used for the chat session).
- Open
the starting solution Begin.sln from last article Ad hoc DiscoveryVisual Studio 2010 must be run in elevated mode. To do this, right-click the Visual Studio 2010 icon and select Run as Administrator.
- Open the SimpleChat.cs (C#) or SimpleChat.vb (Visual Basic) file from the DiscoveryChat project. We can open the code view by selecting the file and pressing F7.
- We can add XML to the endpoint metadata when responding to a discovery probe. To
do this, we will need to add namespaces directives, in particular the System.ServiceModel.Description namespace.C#using System.Linq;using System.Xml.Linq;using System.ServiceModel.Description;Visual BasicImports System.ServiceModel.Description
- Locate the OpenServices method and modify it as shown in the following
code.C#private void OpenServices(){// Create a singleton instance for the hostChatService chatService = new ChatService(this);chatServiceHost = new ServiceHost(chatService, _localAddress);// Create a discovery behaviorvar endpointDiscoveryBehavior = new EndpointDiscoveryBehavior();// Add an extension element with the usernameendpointDiscoveryBehavior.Extensions.Add(new XElement("root",new XElement("Name", this.userName)));// Find the endpointServiceEndpoint simpleEndpoint =this.chatServiceHost.Description.Endpoints.Find(typeof(ISimpleChatService));// Add our behavior to the endpoint before opening itsimpleEndpoint.Behaviors.Add(endpointDiscoveryBehavior);ShowStatus("Opening chat service...");chatServiceHost.BeginOpen((result) =>{chatServiceHost.EndOpen(result);ShowStatus("Chat service ready");},null);}Visual BasicPrivate Sub OpenServices()' Create a singleton instance for the hostDim chatService As New ChatService(Me)Me.chatServiceHost = New ServiceHost(chatService, Me._localAddress)' Create a discovery behaviorDim endpointDiscoveryBehavior As New EndpointDiscoveryBehavior()' Add an extension element with the usernameendpointDiscoveryBehavior.Extensions.Add(<root><Name><%= Me.UserName %></Name></root>)' Find the endpointDim simpleEndpoint = Me.chatServiceHost.Description.Endpoints.Find(GetType(ISimpleChatService))' Add our behavior to the endpoint before opening itsimpleEndpoint.Behaviors.Add(endpointDiscoveryBehavior)Me.ShowStatus("Opening chat service...")Me.chatServiceHost.BeginOpen(Sub(result)chatServiceHost.EndOpen(result)Me.ShowStatus("Chat service ready")End Sub, Nothing)End SubNote: (For Visual Basic users) The above code snippet uses implicit typing. You will need to set Option Infer On in the VB file or set Option Infer at the project level.
- Next we need to add
code to look for this metadata when doing discovery of other services. Add the GetPeerName
method which returns the first node named “Name” from the extension metadata
right after the OpenServices method.C#private static string GetPeerName(EndpointDiscoveryMetadata metadata){XElement peerNameElement =metadata.Extensions.Elements("Name").FirstOrDefault();if (peerNameElement != null)return peerNameElement.Value;return null;}Visual BasicPrivate Shared Function GetPeerName(ByVal metadata As EndpointDiscoveryMetadata) As StringDim peerNameElement = metadata.Extensions.If peerNameElement IsNot Nothing Then Return peerNameElement.ValueReturn NothingEnd Function
- Now that the name is
discoverable as well as the service endpoint, we need to modify the PopulateUserList method to invoke the GetPeerName method. If the name node
exists, the PeerUser class will use
it as the display name in the list box. To do this, replace the current call to
the AddUser method with the
following one.C#private void PopulateUserList(EndpointDiscoveryMetadata endpointDiscoveryMetadata){if (!EndpointIsSelf(endpointDiscoveryMetadata.Address.Uri)){this.AddUser(new PeerUser(GetPeerName(endpointDiscoveryMetadata), endpointDiscoveryMetadata.Address));this.EnableUsersBox();}}Visual BasicPrivate Sub PopulateUserList(ByVal endpointDiscoveryMetadata As EndpointDiscoveryMetadata)If Not Me.EndpointIsSelf(endpointDiscoveryMetadata.Address.Uri) ThenMe.AddUser(New PeerUser(GetPeerName(endpointDiscoveryMetadata), endpointDiscoveryMetadata.Address))Me.EnableUsersBox()End IfEnd Sub
- Press Ctrl+Shift+B to build the solution.
- Press Ctrl+F5 to start an instance of the DiscoveryChat application without debugging.
- Switch back to Visual Studio and press Ctrl+F5 again to launch another instance of the application.
- Switch to one of the instances of DiscoveryChat.exe and setup the chat as follows:
a. User Name: YallaTech
b. Click Sign In - Switch to the other DiscoveryChat.exe instance and setup the chat as follows:
a. Username: Besho
b. Click Sign In - Besho's chat window will discover YallaTech’s after signing in. Switch to YallaTech’s chat window and click on the Discover Users button to find Besho
- We should see the
other instance’s username appear in the Available
Users pane. You can double-click on it to start a chat.Extensions allow us to send the username in discovery metadata
- Close both instances of the DiscoveryChat application
No comments:
Post a Comment