You are currently browsing all posts tagged with 'xmpp'.
Round III, now with BOSH.
After attempt 1 and attempt 2 trying to connect XIFF to ejabberd without applying any patch to ejabberd I finally tried with BOSH connection and IT WORKED!!!
Below are the steps I followed to test a chat example.
- install latest SVN XIFF version (Checked out revision 10959)
export TEST_DIR=/tmp/xiffstep1
mkdir -p $TEST_DIR/xiff
cd $TEST_DIR/xiff
svn co http://svn.igniterealtime.org/svn/repos/xiff/trunk/src/org org
- install latest SVN ejabberd version (revision 1867)
cd $TEST_DIR
svn co http://svn.process-one.net/ejabberd/trunk/ ejabberd_src
cd $TEST_DIR/ejabberd_src/src
./configure --prefix=$TEST_DIR/ejabberd
make
sudo su
make install
- install mod_http_bind in ejabberd and load module in ejabberd.cfg (see this article).
cd $TEST_DIR/
svn co http://svn.process-one.net/ejabberd-modules ejabberd_modules_src
cd $TEST_DIR/ejabberd_modules_src/http_bind/trunk
./build.sh
sudo su
cp ebin/*.beam $TEST_DIR/ejabberd/lib/ejabberd/ebin/
# load mod_http_bind in ejabberd.cfg: {mod_http_bind,[]},
# add request_handler in ejabberd.cfg: {request_handlers, [{["http-bind"], mod_http_bind}]}
cd $TEST_DIR/ejabberd/etc/ejabberd
wget http://www.keoko.net/wp-content/uploads/2009/02/ejabberd.cfg
- setup ejabberd and create two users (sender, receiver).
cd $TEST_DIR/ejabberd/sbin
./ejabberdctl start
./ejabberdctl register user1 localhost user1
./ejabberdctl register user2 localhost user2
- install nginx and configure it as reverse proxy to ejabberd
sudo apt-get install nginx
sudo vim /usr/local/nginx/conf/nginx.conf
# add the following lines after location / block
location /xmpp-httpbind {
proxy_pass http://localhost:5280/http-bind;
break;
}
sudo killall nginx
sudo /usr/local/nginx/sbin/nginx
- get chat example files: XIFFstep1BOSH.mxml and TestChatBosh.as (this example is based on this article).
cd $TEST_DIR/xiff
wget http://www.keoko.net/wp-content/uploads/2009/02/xiffstep1bosh.mxml
wget http://www.keoko.net/wp-content/uploads/2009/02/testchatbosh.as
- create AS3 project “XIFFstep1BOSH” with eclipse + Flex Builder, import library XIFF and example file into the project and run the application.
# run eclipse
File > New > Flex Project -> Project Name: XIFFstep1Bosh
Delete > XIFFstep1BOSH.mxml
File > Import > General > File System > Next > From directory: $TEST_DIR/xiff
Run > Run
- open another XMPP client (e.g. Psi) with user2.
- send message through the flash application in the browser window that has been opened.
- check the message has been received in the other XMPP client (user2).
Mickaël Rémond was right: XMPP works with flash out of the box … with BOSH connections, not with XML socket connections.
When I was writing Flash and ejabberd experiences article, I thought to include all the detailed steps but I was afraid of repeating once more all the steps. However, after having some doubts whether it was really necessary to apply a patch to ejabberd I think it’s worth to review some of them.
Below are the steps I followed to test a chat example.
- install latest SVN XIFF version (Checked out revision 10959)
export TEST_DIR=/tmp/xiffstep1
mkdir -p $TEST_DIR/xiff
cd $TEST_DIR/xiff
svn co http://svn.igniterealtime.org/svn/repos/xiff/trunk/src/org org
- install latest SVN ejabberd version (2.0.2)
cd $TEST_DIR
svn co http://svn.process-one.net/ejabberd/tags/ejabberd-2.0.2/ ejabberd_src
cd $TEST_DIR/ejabberd_src/src
./configure --prefix=$TEST_DIR/ejabberd
make
sudo su
make install
- setup ejabberd and create two users (sender, receiver)
cd $TEST_DIR/ejabberd/sbin
./ejabberdctl start
./ejabberdctl register user1 localhost user1
./ejabberdctl register user2 localhost user2
- get chat example files: xiffstep1.mxml and TestChat.as. Note this example is based on this article.
cd $TEST_DIR/xiff
wget http://www.keoko.net/wp-content/uploads/2009/02/xiffstep1.mxml
wget http://www.keoko.net/wp-content/uploads/2009/02/testchat.as
- create AS3 project “Test1″ with eclipse + Flex Builder, import library XIFF and example file into the project and run the application.
# run eclipse
File > New > Flex Project -> Project Name: XIFFstep1
Delete > XIFFstep1.mxml
File > Import > General > File System > Next > From directory: $TEST_DIR/xiff
Run > Run
- send message through the flash application in the browser window that has been opened.
- check XML/jabber communication.
As pointed out by Mickaël Rémond in this comment, XIFF is not XMPP compliant. It’s clear on the XML request. However, I still don’t see how to connect XIFF with ejabberd without applying the patch mentioned on the first part. BOSH seems the only alternative.
Any suggestion?
After finding out a site with a fishtank where each fish notified the presence of some jabber user (now it’s a christmas tree) I thought it would be interesting to do the same with flash and add some more dynamism (e.g. using events, mood, …) to the fishes.
The rest of the story is here:
- So the first thing was to find a Flash library to do all the XMPP communication with ejabberd through BOSH. Rapidly I googled and all links pointed to XIFF. So far, so good.
- Some IDE to work with Flash in linux. Eclipse with Flex Builer to the rescue following this notes. Some java issues, but not more than 1 hour to have Flex “Hello world” application up and running.
- Let’s look at some XIFF examples … and what? there is no example nor even documentation … except for some 4 examples on this site: chat, roster, multiuser chat room and invitations.
- Test the examples with ejabberd and … failed!!! This was getting harder than expected. Let’s check the Flex traces what was wrong. No way. I was about to cry when I got to a site that recommended me to remove the distribution flashplugin package and install the Adobe’s one and … well it worked.
sudo apt-get remove flashplugin-nonfree
- With Flex trace now working I didn’t get too many answers, so I dug into the jabber packets with Wireshark and discovered the XMPP stream communication was closed unexpectedly. Time to google and see I needed to apply a patch to ejabberd to work with flash.
- At this point I was actually crying. What was supposed to be a couple of hours of fun, it was being a trip to hell!!! So, with tears in my eyes I installed Erlang R12B-5 following these steps. Downloaded ejabberd 2.0.2, applied the patch, unpacked it, run configure script, compiled and installed it. WHAT???
- I said ejabberd 2.0.2 and the patch I found was for 2.0.0. Full of tears I adapted the patch for ejabberd 2.0.2 and then applied the patch, unpacked it, run configure script, compiled and installed it.
- Voilá! Chat (first example) working with AS3.
- Roster (second example) failed with below AS3 exception.
Error: No class registered for interface 'mx.resources::IResourceManager'
- At this point I was looking how to express my level of depression with my jabber mood. Googling and googling finally I got to this post that recommended me to load the affected class at the very beginning of the application and so I did it including the following lines in my class constructor. It worked.
// http://www.igniterealtime.org/community/thread/34519
// Do what FlexModuleFactory does, only by hand.
var resourceManagerImpl:Object = flash.system.ApplicationDomain.currentDomain.getDefinition("mx.resources::ResourceManagerImpl");
//mx.core.Singleton.registerClass("mx.resources::IResourceManager", Class(resourceManagerImpl));
Singleton.registerClass("mx.resources::IResourceManager", Class(resourceManagerImpl));
- Time to test multiuser chat room (third example). Press debug button and then what??? What the **ll is doing??? I knew I’d just entered to the world of pain. I was feeling the pain until I stumbled upon iaminlikewithyou and played balloono until 3 AM. This site was really cool and seemed that they were using XMPP for the game communication but not really sure.
- Multiuser chat room (round II). I read the example code and realized that I had to create a multiuser chat room and invite the user from an XMPP client (e.g. Pidgin) to work. That was not so difficult but the morale was already killed in the 5th step.
- Invitations (fourth example) was really easy probably at this stage I was trained to stand any suffering.
- No mood to create any fishtank nor christmas tree!!!
To sum up:
- XIFF
- no documentation
- no examples
- not work with AS3 out of the box
- support for chat, roster, MUC, invitations and BOSH although the latter I’ve not tested.
- ejabberd
After reading “Beyond REST? Building Data Services with XMPP PubSub” and other articles about PubSub with XMPP, I decided it would be worth to test it. However, I didn’t find any complete step by step guide in how to test it with ejabberd as XMPP server and XMPP4R as XMPP client.
Below are the steps I followed to test a subscriber (user “sub”) waiting for items published to the node (”home/localhost/pub/updates”) for the publisher (user “pub”). Note you can add as many subscribers/publishers as you want.
- install ejabberd (XMPP server). I followed instructions of this article (spanish) or article (english) without any surprise.
- create two ejabberd users: “pub” (the publisher) and “sub” (the subscriber).
sudo ejabberdctl register pub localhost pub
sudo ejabberdctl register sub localhost sub
- install XMPP4R Ruby gem.
sudo gem install xmpp4r
- create file nodecreator.rb. See code below.
#! /usr/bin/ruby
require "rubygems"
require "xmpp4r"
require "xmpp4r/pubsub"
require "xmpp4r/pubsub/helper/servicehelper.rb"
require "xmpp4r/pubsub/helper/nodebrowser.rb"
require "xmpp4r/pubsub/helper/nodehelper.rb"
include Jabber
Jabber::debug = true
service = 'pubsub.localhost'
jid = 'pub@localhost/laptop'
password = 'pub'
client = Client.new(JID.new(jid))
client.connect
client.auth(password)
client.send(Jabber::Presence.new.set_type(:available))
pubsub = PubSub::ServiceHelper.new(client, service)
pubsub.create_node('home/localhost/pub/')
pubsub.create_node('home/localhost/pub/updates')
- create file publisher.rb. See code below.
#! /usr/bin/ruby
require "rubygems"
require "xmpp4r"
require "xmpp4r/pubsub"
require "xmpp4r/pubsub/helper/servicehelper.rb"
require "xmpp4r/pubsub/helper/nodebrowser.rb"
require "xmpp4r/pubsub/helper/nodehelper.rb"
include Jabber
Jabber::debug = true
jid = 'pub@localhost/laptop'
password = 'pub'
service = 'pubsub.localhost'
node = 'home/localhost/pub/updates'
# connect XMPP client
client = Client.new(JID.new(jid))
# remove "127.0.0.1" if you are not using a local ejabberd
client.connect("127.0.0.1")
client.auth(password)
client.send(Jabber::Presence.new.set_type(:available))
# create item
pubsub = PubSub::ServiceHelper.new(client, service)
item = Jabber::PubSub::Item.new
xml = REXML::Element.new("greeting")
xml.text = 'hello world!'
item.add(xml);
# publish item
pubsub.publish_item_to(node, item)
- create file subscriber.rb. See code below.
#! /usr/bin/ruby
require "rubygems"
require "xmpp4r"
require "xmpp4r/pubsub"
require "xmpp4r/pubsub/helper/servicehelper.rb"
require "xmpp4r/pubsub/helper/nodebrowser.rb"
require "xmpp4r/pubsub/helper/nodehelper.rb"include Jabber
#Jabber::debug = true
jid = 'sub@localhost/laptop'
password = 'sub'
node = 'home/localhost/pub/updates'
service = 'pubsub.localhost'
# connect XMPP client
client = Client.new(JID.new(jid))
# remove "127.0.0.1" if you are not using a local ejabberd
client.connect("127.0.0.1")
client.auth(password)
client.send(Jabber::Presence.new.set_type(:available))
sleep(1)
# subscribe to the node
pubsub = PubSub::ServiceHelper.new(client, service)
pubsub.subscribe_to(node)
subscriptions = pubsub.get_subscriptions_from_all_nodes()
puts "subscriptions: #{subscriptions}\n\n"
puts "events:\n"
# set callback for new events
pubsub.add_event_callback do |event|
begin
event.payload.each do |e|
puts e,"----\n"
end
rescue
puts "Error : #{$!} \n #{event}"
end
# infinite loop
loop do
sleep 1
end
- run nodecreator.rb. It creates the XMPP node “home/localhost/pub/updates”. It creates first the node “home/localhost/pub” and then the “home/localhost/pub/updates”. Seems quite obvious but I spent some hours after I got it.
- check the nodes have been created. I used the discovery service functionality of Psi client.

- run subscriber.rb file. The “sub” user subscribes to the node ‘updates’ and waits for items in the “updates” node. Be aware you should close any XMPP connection with users “pub” and “sub” in case you are using any XMPP client such as Pidgin, Psi,… otherwise it won’t work.
- run publisher.rb file. It will send a message “<greetings>hello world!”</greetings> to the subscriber. Run it as many times as you want.
- If everything goes well yo will see in the subscriber screen a message like this.
subscriptions: <subscription node='home/localhost/pub/updates' jid='sub@localhost' subscription='subscribed' xmlns='http://jabber.org/protocol/pubsub'/>
events:
<items node='home/localhost/pub/updates'><item id='3376'><greeting>hello world!</greeting></item></items>
----
Good Luck!
For this test, I used the following versions:
- Operating System: Ubuntu 8.04
- Ruby: 1.8.6
- XMPP4R: 0.4
- ejabberd: 1.1.4