Click here to Skip to main content
15,884,388 members
Articles / Programming Languages / XML

A simple XMPP-client based on Workflow Foundation

Rate me:
Please Sign up or sign in to vote.
4.44/5 (8 votes)
27 Dec 2009CPOL3 min read 64.6K   3.8K   30   14
This article describes a simple XMPP client application based on Workflow Foundation.

Image 1

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:

XML
<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:

C#
....
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)


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

Comments and Discussions

 
QuestionGetting Error. Pin
Nishant285216-Jul-15 19:42
Nishant285216-Jul-15 19:42 
AnswerRe: Getting Error. Pin
Ilya Builuk19-Jul-15 11:10
Ilya Builuk19-Jul-15 11:10 
QuestionHow do you build the project? Pin
nveri24-Feb-10 10:39
nveri24-Feb-10 10:39 
AnswerRe: How do you build the project? Pin
Ilya Builuk24-Feb-10 19:43
Ilya Builuk24-Feb-10 19:43 
GeneralRe: How do you build the project? Pin
nveri26-Feb-10 6:02
nveri26-Feb-10 6:02 
Questiondoes it work with Openfire Sever? Pin
samfayad8-Feb-10 10:32
samfayad8-Feb-10 10:32 
AnswerRe: does it work with Openfire Sever? Pin
Ilya Builuk9-Feb-10 7:13
Ilya Builuk9-Feb-10 7:13 
AnswerRe: does it work with Openfire Sever? Pin
Ilya Builuk9-Feb-10 21:08
Ilya Builuk9-Feb-10 21:08 
GeneralRe: does it work with Openfire Sever? Pin
Freddy Rogers24-May-10 18:34
Freddy Rogers24-May-10 18:34 
GeneralRe: does it work with Openfire Sever? Pin
Freddy Rogers24-May-10 19:08
Freddy Rogers24-May-10 19:08 
Questionwhere is the sample code for the XMPP-client? Pin
Huisheng Chen27-Dec-09 15:02
Huisheng Chen27-Dec-09 15:02 
AnswerRe: where is the sample code for the XMPP-client? Pin
Ilya Builuk27-Dec-09 21:14
Ilya Builuk27-Dec-09 21:14 
GeneralRe: where is the sample code for the XMPP-client? Pin
Huisheng Chen28-Dec-09 1:10
Huisheng Chen28-Dec-09 1:10 
GeneralRe: where is the sample code for the XMPP-client? Pin
Ilya Builuk28-Dec-09 2:05
Ilya Builuk28-Dec-09 2:05 

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

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