Click here to Skip to main content
Click here to Skip to main content

A simple XMPP-client based on Workflow Foundation

, 27 Dec 2009
Rate this:
Please Sign up or sign in to vote.
This article describes a simple XMPP client application based on Workflow Foundation.

Introduction

The article describes a simple XMPP client application based on the Windows Workflow Foundation, which allows to send and receive messages and also to add and remove contacts from your contact list.

Background

Extensible Messaging and Presence Protocol

The Extensible Messaging and Presence Protocol (XMPP) is an open technology for real time communication, using Extensible Markup Language (XML) as the base format for exchanging information. In essence, XMPP provides a way to send small pieces of XML from one entity to another in close to real time.

The XMPP protocol is taken as the RFC standard, and is described by the following documents:

  • RFC 3920 Extensible Messaging and Presence Protocol: Core
  • RFC 3921 Extensible Messaging and Presence Protocol: Instant Messaging and Presence

Windows Workflow Foundation

Windows Workflow Foundation (WF) is a Microsoft technology for defining, executing, and managing workflows. This technology was first released in November 2006 as a part of .NET Framework 3.0.

WF is a special runtime environment that manages the execution of programs that are composed of resumable program statements. In WF, a resumable program statement is called an Activity. A resumable program is a composition of activities. In WF, such a program is often called a Workflow.

Using the Code

The project consists of two libraries and an XOML-file: JabberClient.dll (root namespace is Jabber.Client), WorkflowActivities.dll (root namespace is Workflow), and Sequence.xml.

Namespace Jabber.Client

The Jabber.Client namespace includes the types for the XMPP client realization with minimal functionality, which are presented in the following list:

  • Jabber.Client.Core.TcpBinder wraps the standard System.Net.Sockets.Socket class.
  • Jabber.Client.Core.ClientState enumerates the possible client states.
  • Jabber.Client.Xml.PacketBuilder contains the methods for building XML-strings for XMPP-server requests (authentication, contact list request, message sending, etc.).
  • Jabber.Client.Xml.PacketParser contains the methods for XMPP-server response parsing.
  • Jabber.Client.Cryptography.DigestMD5Auth implies digest authentication according to RFC2831.
  • Jabber.Client.JabberClient encapsulates all of XMPP-client logic.

Namespace Worflow

The Worflow namespace includes the set of activities and helper classes which help to specify the program algorithm. You can see the list of main activities below.

  • Workflow.Activities.Receiver retrieves the message from a Queue, converts it with the help of the ReceiveMethod method of the ReceiveType class of the AssemblyFile assembly, and calls the OnReceived method of the IWorkflowDataService interface.
  • Workflow.Activities.Sender retrieves the message from a Queue, converts it with the help of the SendMethod method of the SendType class of the AssemblyFile assembly, and calls the Send method of the IWorkflowDataService interface.
  • Workflow.Activities.StateSendAndReceive sends the message and receives the response. For it to work, the activity needs these properties: ReceiveMethod, ReceiveType, AssemblyFile, SendMethod, SendType, and Context. The Context property is used as in-out params.
  • Workflow.Activities.Sequence is a type of CompositeActivity, which sequentially executes its child activities.
  • Workflow.Activities.Switch emulates a switch instruction.

Thus, the simple XMPP client's XOML-file is represented below:

<Sequence x:Name="root"
   xmlns="http://Workflow/Activities"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:wf="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
  <Switch  x:Name="sw1">
    <StateSequence x:Name="Auth" Queue="AuthInputQueue">
      <StateSendAndReceive Name="step1_0" AssemblyFile="JabberClient.dll" 
        SendType="Jabber.Client.Xml.PacketBuilder"  SendMethod="AuthStreamHeader" 
        ReceiveType="Jabber.Client.Xml.PacketParser" ReceiveMethod="AuthStreamHeader1" 
        Context="{wf:ActivityBind Auth, Path=Context}" />
      <StateSendAndReceive Name="step1_1" AssemblyFile="JabberClient.dll" 
            ReceiveType="Jabber.Client.Xml.PacketParser" 
            ReceiveMethod="AuthStreamHeader2" 
            Context="{wf:ActivityBind step1_0, Path=Context}" />
            ........
    </StateSequence>
    <Receiver x:Name="Receive" Queue="ReceiveQueue" 
            AssemblyFile="JabberClient.dll" 
            ReceiveType="Jabber.Client.Xml.PacketParser" 
            ReceiveMethod="ResponseMessage" />
    <Sender x:Name="Send" Queue="SendQueue" 
            AssemblyFile="JabberClient.dll" 
            SendType="Jabber.Client.Xml.PacketBuilder" 
            SendMethod="ChatMessage"/>
    <Sender x:Name="Status" Queue="StatusQueue" 
            AssemblyFile="JabberClient.dll" 
            SendType="Jabber.Client.Xml.PacketBuilder" 
            SendMethod="PresenceShow"/>
    <Sender x:Name="Roster" Queue="RosterQueue" 
            AssemblyFile="JabberClient.dll" 
            SendType="Jabber.Client.Xml.PacketBuilder" 
            SendMethod="Roster"/>
    <Sender x:Name="Subscribe" Queue="RosterQueue" 
            AssemblyFile="JabberClient.dll" 
            SendType="Jabber.Client.Xml.PacketBuilder" 
            SendMethod="Subscribe"/>
    <Sender x:Name="Unsubscribe" Queue="RosterQueue" 
            AssemblyFile="JabberClient.dll"
            SendType="Jabber.Client.Xml.PacketBuilder" 
            SendMethod="Unsubscribe"/>
  </Switch>
</Sequence>

It follows from the XOML-file that the StateSequence activity performs the client authentication on the XMPP-server according to RFC2831. Dynamic binding of the Context property is used in child Activities.

An example of using a simple XMPP-client is shown below:

....
using Jabber.Client;
using Jabber.Client.Core;
....

using (JabberClient jabber =
            new JabberClient("jabber.org", "vba32cc", "1234qwer"))
{
    //subscribe to events
    jabber.Authentificated += new EventHandler(jabber_Authentificated);
    jabber.RosterReceived += new RosterHandler(jabber_RosterReceived);
    jabber.MessageReceived += new MessageHandler(jabber_MessageReceived);

    Console.WriteLine("Authentification...");
    jabber.Auth();
    string s = Console.ReadLine();
    Console.WriteLine("Client state={0}", jabber.State);
    while (!string.IsNullOrEmpty(s))
    {
        if (jabber.State == ClientState.Authentificated)
        {
            Contact contact = new Contact("", "veleslaff@jabber.ru");
            jabber.AddToContacts(contact); //Add to contacts
            jabber.SetStatusForContact(contact, UserStatus.Online);//Set status
            jabber.Send(contact, s); //Send  message
            jabber.Contacts(); //Get roster list
        }
        s = Console.ReadLine();
    }
}
....

Points of Interest

The error handling in the workflow library and the host program's notification need improving. Classes in the Jabber.Client.Xml namespace need refactoring.

History

  • 27th December, 2009: First version of a simple XMPP-client with basic functionality.
  • 28th December, 2009: Updated the sample project.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ilya Builuk
Software Developer (Senior) Nokia
Germany Germany
Interested in design/development of framework functionality using the best patterns and practices.

Comments and Discussions

 
QuestionHow do you build the project? Pinmembernveri24-Feb-10 10:39 
AnswerRe: How do you build the project? PinmemberIlya Builuk24-Feb-10 19:43 
GeneralRe: How do you build the project? Pinmembernveri26-Feb-10 6:02 
Questiondoes it work with Openfire Sever? Pinmembersamfayad8-Feb-10 10:32 
AnswerRe: does it work with Openfire Sever? PinmemberVeleslav9-Feb-10 7:13 
AnswerRe: does it work with Openfire Sever? PinmemberVeleslav9-Feb-10 21:08 
GeneralRe: does it work with Openfire Sever? PinmemberFreddy Rogers24-May-10 18:34 
GeneralRe: does it work with Openfire Sever? PinmemberFreddy Rogers24-May-10 19:08 
Questionwhere is the sample code for the XMPP-client? PinmemberUnruled Boy27-Dec-09 15:02 
AnswerRe: where is the sample code for the XMPP-client? PinmemberVeleslav27-Dec-09 21:14 
GeneralRe: where is the sample code for the XMPP-client? PinmemberUnruled Boy28-Dec-09 1:10 
GeneralRe: where is the sample code for the XMPP-client? PinmemberVeleslav28-Dec-09 2:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 27 Dec 2009
Article Copyright 2009 by Ilya Builuk
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid