Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Smack, XMPP, and GTalk

, 2 Jun 2011 Apache
Rate this:
Please Sign up or sign in to vote.
Includes sample code that can connect to the GoogleTalk server and get a list of all your friends.

I had to work on project which supports P2P file transfers and it is then when I thought, why not use an existing framework rather than building a new one from scratch. I had worked on Smack/ Openfire XMPP libraries around 6 years ago and revisited them for the above purpose.

Jabber /XMPP servers support P2P file transfer protocols and follow the Jingle specification. So I thought of testing how to use the Smack API to build a chat client in Java. This tutorial will illustrate the same from Flex/Flash.

Here is a sample code that can connect to the GoogleTalk server and get a list of all your friends. This also shows an example of how to send a chat message to a given user.

Here are a few terms you need to understand before you start using the XMPP libraries.

Roster

Roster is the name given to the list of contacts which appears in one’s chat client. In Google Talk terms, it is the list of friends you would see once you login. The elements of the roster are your contacts. Each of these items is identified by a unique identifier called JID (Jabber Identifier).

Rosters are stored on the server so that the XMPP client may retrieve them each time the user logs in.

Message

This is one of the three fundamental Stanzas in XMPP. (The other two are IQ and Presence.) As it is obvious, a Message Stanza is used for sending IMs (Instant Messages).

IQ

This is another very important Stanza. IQ stands for Info/Query. It is similar to traditional Request/Response paradigms such as HTTP. An IQ Stanza can be one of four types, “get”, “set”, “result”, or “error”. The first two are requests or queries while the last two are responses or information. An IQ Stanza can wrap various kinds of elements. Let’s see one such example here.

Juliet logs onto her XMPP client. The client sends an XMPP IQ Stanza of type “get” to the gmail.com server requesting her roster.

<iq from=”ashwin@gmail.com” type=”get” id=”roster_1″> <query xmlns=”jabber:iq:roster”/> </iq>

Presence

This is the third Stanza type specified by the XMPP Core. In laymen terms, Presence simply refers to the availability or status of a contact.

Now that you are familiar with some basic terms that you will come across in the library, I’ll start pasting some working code which can be tested against GTtalk.

Here is a sample HelloWorld code:

package com.linkwithweb.demos;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;

/**
 * @author Ashwin Kumar
 *
 */
public class HelloWorld {
    static JabberSmackAPI api = new JabberSmackAPI();

    /**
     * @param args
     */
    public static void main(String[] args) {
        connectTOGTalk();
    }

    /**
     *
     */
    private static void connectTOGTalk() {
        // Create XMPP connection to gmail.com server
        XMPPConnection connection = new XMPPConnection("gmail.com");

        try {
            // You have to put this code before you
            // login(Required for Gtalk and not for Jabber.org)
            SASLAuthentication.supportSASLMechanism("PLAIN", 0);
            // Connect
            connection.connect();

            // Login with appropriate credentials
            connection.login("madnesstestuser@gmail.com", "madnesstestuser");

            // Get the user's roster
            Roster roster = connection.getRoster();

            // Print the number of contacts
            System.out.println("Number of contacts: " + roster.getEntryCount());
            api.setConnection(connection);
            // Enumerate all contacts in the user's roster
            for (RosterEntry entry : roster.getEntries()) {
                System.out.println("User: " + entry.getUser());
                if (entry.getUser().contains("pandumalladi")) {
                    Chat chat = connection.getChatManager().createChat(
                            entry.getUser(), api);
                    chat.sendMessage("Testing Hi");
                    api.fileTransfer(
                            "C:\\development\\Ashwin\\Jingle\\JitSI\\Test.txt",
                            entry.getUser());

                }
            }

            connection.disconnect();
        } catch (XMPPException e) {
            // Do something better than this!
            e.printStackTrace();
        }
    }

    /**
     *
     */
    public static void connectToJabber() {
        ConnectionConfiguration cc = new ConnectionConfiguration("jabber.org",
                5222, "jabber.org");
        XMPPConnection connection = new XMPPConnection(cc);
        try {
            connection.connect();

            // You have to put this code before you login
            SASLAuthentication.supportSASLMechanism("PLAIN", 0);

            // You have to specify your Jabber ID addres WITHOUT @jabber.org at the end
            connection.login("your.jabber", "password", "resource");

            // See if you are authenticated
            System.out.println(connection.isAuthenticated());

        } catch (XMPPException e1) {
            e1.printStackTrace();
        }
    }
}

Here is the sample utility class used:

/**
 *
 */
package com.linkwithweb.demos;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferNegotiator;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;

/**
 * API With some Utitlity Methods
 * @author Ashwin Kumar
 *
 */
public class JabberSmackAPI implements MessageListener {

    XMPPConnection connection;
    private FileTransferManager manager;

    public void setConnection(XMPPConnection connection) {
        this.connection = connection;
        manager = new FileTransferManager(connection);
    }

    public JabberSmackAPI() {
    }

    public void login(String userName, String password) throws XMPPException {
        ConnectionConfiguration config = new ConnectionConfiguration(
                "localhost", 5222, "Work");
        connection = new XMPPConnection(config);

        connection.connect();
        connection.login(userName, password);
    }

    public void fileTransfer(String fileName, String destination)
            throws XMPPException {

        // Create the file transfer manager
        // FileTransferManager manager = new FileTransferManager(connection);
        FileTransferNegotiator.setServiceEnabled(connection, true);
        // Create the outgoing file transfer
        OutgoingFileTransfer transfer = manager
                .createOutgoingFileTransfer(destination);

        // Send the file
        transfer.sendFile(new File(fileName), "You won't believe this!");
        try {
            Thread.sleep(10000);
        } catch (Exception e) {
        }
        System.out.println("Status :: " + transfer.getStatus() + " Error :: "
                + transfer.getError() + " Exception :: "
                + transfer.getException());
        System.out.println("Is it done? " + transfer.isDone());
    }

    public void sendMessage(String message, String to) throws XMPPException {
        Chat chat = connection.getChatManager().createChat(to, this);
        chat.sendMessage(message);
    }

    public void displayBuddyList() {
        Roster roster = connection.getRoster();
        Collection<RosterEntry> entries = roster.getEntries();

        System.out.println("\n\n" + entries.size() + " buddy(ies):");
        for (RosterEntry r : entries) {
            System.out.println(r.getName());
        }
    }

    public void disconnect() {
        connection.disconnect();
    }

    public void processMessage(Chat chat, Message message) {
        if (message.getType() == Message.Type.chat)
            System.out.println(chat.getParticipant() + " says: "
                    + message.getBody());
    }

    public static void main(String args[]) throws XMPPException, IOException {
        // declare variables
        JabberSmackAPI c = new JabberSmackAPI();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String msg;

        // turn on the enhanced debugger
        XMPPConnection.DEBUG_ENABLED = true;

        // Enter your login information here
        c.login("ashwin", "ashwin@123");

        c.displayBuddyList();

        System.out.println("-----");

        System.out.println("Who do you want to talk to?" + 
               " - Type contacts full email address:");
        String talkTo = br.readLine();

        System.out.println("-----");
        System.out.println("All messages will be sent to " + talkTo);
        System.out.println("Enter your message in the console:");
        System.out.println("-----\n");

        while (!(msg = br.readLine()).equals("bye")) {
            c.sendMessage(msg, talkTo);
        }

        c.disconnect();
        System.exit(0);
    }
}

You can checkout the above project from SVN and test it yourself. Have fun with Jabber.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

Share

About the Author

AshwinRayaprolu
Chief Technology Officer Northalley
United States United States
A Technology evangelist with no technical language barriers. A strong believer that Simple Sofware Is Perfect Software. A staunch proponent of software / documentation automation in all domain's. And finally a true diciple of Google Search.

Comments and Discussions

 
QuestionThanks Pinmembersree.tux8-Apr-14 20:57 
Questionadd smack.jar into eclipse Pinmemberisaacong9-Dec-13 3:08 
hi,
 
can you show me the steps to add smack.jar into eclipse? thanks.
QuestionAre you studying in XMPP? Pinmembergodsolio27-Apr-13 13:16 

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.141022.2 | Last Updated 2 Jun 2011
Article Copyright 2011 by AshwinRayaprolu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid