Tuesday, December 11, 2012

Announcements

Most chat applications notify you when other users sign in. This application can discover other users but it would be better if we were notified when other users sign in. Discovery supports this feature with announcements

  1. Open the starting solution Begin.sln from last article Metadata Extensions 
       Watch Out
    Visual Studio 2010 must be run in elevated mode. To do this, right-click the Visual Studio 2010 icon and select Run as Administrator.
  2. Open the App.config file in the DiscoveryChat project.
  3. To take advantage of announcements, we will need to add an announcement endpoint. To do this, locate the DiscoveryBehavior behavior we added earlier in this lab and modify it as shown in the following code.
    XML
    <behavior name="DiscoveryBehavior">
      <serviceDiscovery>
        <announcementEndpoints>
          <endpoint name="udpEndpointName"
                    kind="udpAnnouncementEndpoint"/>
        </announcementEndpoints>
      </serviceDiscovery>
    </behavior>
       Announcement Endpoint
    Adding an announcement endpoint to the discovery service behavior creates a default announcement client for the service. This guarantees that the service will send an online and offline announcement when the service is opened and closed respectively.
  4. Now we need to add an announcement service to our code to receive announcement messages. Open SimpleChat.cs (C#) or SimpleChat.vb (Visual Basic) and declare the following member fields; we can do that after the discoveryClient member declaration.
    C#
    private AnnouncementService announcementService;
                    private ServiceHost announcementServiceHost;
    Visual Basic
    Private WithEvents announcementService As AnnouncementService
    Private announcementServiceHost As ServiceHost
  5. Create the OpenAnnouncementService method as shown in the following code.
    C#
    private void OpenAnnouncementService()
    {
        this.announcementService = new AnnouncementService();

        // Add event handlers
        this.announcementService.OnlineAnnouncementReceived +=
            new EventHandler<AnnouncementEventArgs>(this.OnOnlineAnnouncement);
        this.announcementService.OfflineAnnouncementReceived +=
            new EventHandler<AnnouncementEventArgs>(this.OnOfflineAnnouncement);

        // Create the service host with a singleton
        this.announcementServiceHost = new ServiceHost(this.announcementService);

        // Add the announcement endpoint
        this.announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());

        // Open the host async
        this.announcementServiceHost.BeginOpen(
            (result) =>
            {
                announcementServiceHost.EndOpen(result);
            },
            null);
    }
    Visual Basic
    Private Sub OpenAnnouncementService()
        Me.announcementService = New AnnouncementService()

        ' Create the service host with a singleton
        Me.announcementServiceHost = New ServiceHost(Me.announcementService)

        ' Add the announcement endpoint
        Me.announcementServiceHost.AddServiceEndpoint(New UdpAnnouncementEndpoint())

        ' Open the host async
        Me.announcementServiceHost.BeginOpen(Sub(result)
                                         announcementServiceHost.EndOpen(result)
                                             End Sub, Nothing)
    End Sub
    Announcement Service
    The self-hosted implementation of the announcement service exposes two different events you might be interested in when using Announcements: OnlineAnnouncementReceived and OfflineAnnouncementReceived. Those events are fired when Online (Hello) and Offline (Bye) announcement messages are received respectively
  6. Now we need to implement the handlers for these announcements. When new users come online we will add them to the list. Add the OnOnlineAnnouncement method as shown in the following code:
    C#
    private void OnOnlineAnnouncement(object sender, AnnouncementEventArgs e)
    {
        EndpointDiscoveryMetadata metadata =
            e.EndpointDiscoveryMetadata;

        // We are looking for services that
        // implement the ISimpleChatService contract
        FindCriteria criteria =
            new FindCriteria(typeof(ISimpleChatService));

        if (criteria.IsMatch(metadata))
        {
            if (this.GetUser(metadata.Address.Uri) == null)
            {
                this.PopulateUserList(metadata);
            }
        }
    }
    Visual Basic
    Private Sub OnOnlineAnnouncement(ByVal sender As Object,
                                     ByVal e As AnnouncementEventArgs) Handles announcementService.OnlineAnnouncementReceived

        Dim metadata = e.EndpointDiscoveryMetadata

        ' We are looking for services that
        ' implement the ISimpleChatService contract
        Dim criteria As New FindCriteria(GetType(ISimpleChatService))

        If criteria.IsMatch(metadata) And Me.GetUser(metadata.Address.Uri) Is Nothing Then Me.PopulateUserList(metadata)
    End Sub
  7. When users go offline we  will remove them and close any active chat windows. Add the OnOfflineAnnouncement method as shown in the following code:
    C#
    private void OnOfflineAnnouncement(object sender, AnnouncementEventArgs e)
    {
        EndpointDiscoveryMetadata metadata =
            e.EndpointDiscoveryMetadata;

        FindCriteria criteria =
            new FindCriteria(typeof(ISimpleChatService));

        if (criteria.IsMatch(metadata))
        {
            this.RemoveUser(metadata.Address.Uri);
        }
    }
    Visual Basic
    Private Sub OnOfflineAnnouncement(ByVal sender As Object,
                                      ByVal e As AnnouncementEventArgs) Handles announcementService.OfflineAnnouncementReceived

        Dim metadata = e.EndpointDiscoveryMetadata

        Dim criteria As New FindCriteria(GetType(ISimpleChatService))

        If criteria.IsMatch(metadata) Then Me.RemoveUser(metadata.Address.Uri)
    End Sub
  8. Locate the OpenServices method and add a call to OpenAnnouncementService service at the end of the method implementation.
    C#
        this.ShowStatus("Opening chat service...");
        this.chatServiceHost.BeginOpen(
            (result) =>
            {
                chatServiceHost.EndOpen(result);
                this.ShowStatus("Chat service ready");
            },
            null);

        this.OpenAnnouncementService();
    }
    Visual Basic
        Me.ShowStatus("Opening chat service...")
        Me.chatServiceHost.BeginOpen(Sub(result)
                                         chatServiceHost.EndOpen(result)
                                         Me.ShowStatus("Chat service ready")
                                     End Sub, Nothing)

        Me.OpenAnnouncementService()
    End Sub
  9. Press CTRL+SHIFT+B to build the solution.
  10. Press Ctrl+F5 to start an instance of the DiscoveryChat application without debugging.
  11. Switch back to Visual Studio and press Ctrl+F5 again to launch another instance of the application.
  12. Switch to one of the instances of DiscoveryChat.exe and setup the chat as follows:
    a. 
    User Name: YallaTech
    b. 
    Click Sign In
  13. Switch to the other DiscoveryChat.exe instance and setup the chat as follows:
    a. 
    Username: Besho
    b. Click Sign In 
  14. 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.
  15. We should see the other instance’s username appear in the Available Users pane. You can double-click on it to start a chat.
    Users are automatically discovered
    Users are automatically discovered
    1. Verify that the offline announcement is working by clicking the Sign Out button on the Wilma's chat window.  This should cause Fred's window to remove Wilma from the list of available users.
    2. Try signing in and out from both applications.  Each application is aware of the online / offline announcements of the other.
    3. Close both instances of the DiscoveryChat application.
    4. The finale solution of this project is :
      EzzFile

      uploaded

    2 comments:

    1. Hi.. can you upload the project file? I want to learn it... thanks before...

      ReplyDelete

    YallaTech Facebook page