There are many chat applications for android open source that you can use to connect to an XMPP or Jabber server instance. This could be you own server such as Ejabberd or one such as Facebook / yahoo etc.
I have started to look at how to write a basic android XMPP client that I can use to connect to my Ejabberd server. I have pulled a number of sources available to gain knowledge in android, initially stating with Professional Android 2 Application Development.
There are a number other sample applications in this book that will aid in learning the android programming language.
However to understand how to create an XMPP application I started looking at Smack, an XMPP client library.
This is the library you will need to import and refer to when writing your android XMPP client. Google no longer has it's own native XMPP library.
Smack has be heavily patched to work with android devices, re-badged asmack, library downloads are available from http://code.google.com/p/asmack/
.
Once you have this imported into your project workspace you can now write a basic chat client. I used the following example code for my first point of call:
http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/
After understanding what each bit of code here meant I was able to write my own similar app. Initially the original sample I'm going to show is very similar to the link above, so I cannot take full credit, I'm just sharing resources.
I have now heavily added to the app with shared preferences custom views and content providers etc, I may share the source in later posts.
You will need to write xml layouts to go with the code but the code behind the main application is as follows:
notice the org.jivesoftware.smack imports:
ChatClient.java:
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
public class ChatClient extends Activity {
private ArrayList<String> messages = new ArrayList();
private Handler handler = new Handler();
private xmppsettings settings;
private EditText recipient;
private EditText text;
private ListView list;
private XMPPConnection connection;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
recipient = (EditText) this.findViewById(R.id.recipient);
text = (EditText) this.findViewById(R.id.text);
list = (ListView) this.findViewById(R.id.messageList);
setListAdapter();
//Window for getting settings
settings = new xmppsettings(this);
//Listener for chat message
Button send = (Button) this.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String to = recipient.getText().toString();
String text1 = text.getText().toString();
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text1);
connection.sendPacket(msg);
messages.add(connection.getUser() + ":");
messages.add(text1);
setListAdapter();
}
});
}
//Called by settings when connection is established
public void setConnection (XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
//Packet listener to get messages sent to logged in user
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
messages.add(fromName + ":");
messages.add(message.getBody());
handler.post(new Runnable(){
public void run() {
setListAdapter();
}
});
}
}
}, filter);
}
}
private void setListAdapter() {
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this, R.layout.list, messages);
list.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.settings:
settings.show();
return true;
case R.id.quit:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
xmppsettings.java: (I have made this a menu item)
import android.app.Dialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
//settings get input and then connection is established
public class xmppsettings extends Dialog implements android.view.View.OnClickListener {
private ChatClient chatClient;
public xmppsettings(ChatClient chatClient){
super(chatClient);
this.chatClient = chatClient;
}
protected void onStart() {
super.onStart();
setContentView(R.layout.settings);
setTitle("Connection Settings");
Button ok = (Button) findViewById(R.id.ok);
ok.setOnClickListener(this);
}
public void onClick(View v) {
String host = getText(R.id.host);
String port = getText(R.id.port);
String service = getText(R.id.service);
String username = getText(R.id.userid);
String password = getText(R.id.password);
// Create connection
ConnectionConfiguration connectionConfig =
new ConnectionConfiguration(host, Integer.parseInt(port), service);
XMPPConnection connection = new XMPPConnection(connectionConfig);
try {
connection.connect();
} catch (XMPPException ex) {
chatClient.setConnection(null);
}
try {
connection.login(username, password);
// Set status to online / available
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
chatClient.setConnection(connection);
} catch (XMPPException ex) {
chatClient.setConnection(null);
}
dismiss();
}
private String getText(int id) {
EditText widget = (EditText) this.findViewById(id);
return widget.getText().toString();
}
}
After these initial files I then when one to create a shared preferences which will save the settings that a user inputs.
Also then when on to write a separate array adapter within the chatclient.java class which then aided in the creation of a content provider to store the messages in a db.
This is the application at the most basic, but will get you started in developing any high end chat app.
Showing posts with label jabber. Show all posts
Showing posts with label jabber. Show all posts
Tuesday, 18 January 2011
Writing a basic XMPP/Jabber chat application for Android
Labels:
android,
app,
asmack,
chat,
chat client,
development,
Ejabberd,
Facebook,
jabber,
library,
smack,
xmpp
Tuesday, 7 December 2010
Load testing Ejabberd XMPP Server with Tsung
In order to determine how many servers and what technology is required for a back end Jabber/XMPP server instance I used Tsung to complete a load test.
Tsung is another open source tool written in erlang. Tsung can be used to load test on multiple protocols, including HTTP, LDAP, PostgreSQL and Jabber/XMPP servers.
Tsung can be used to simulate real users and log them all in simultaneously, stress testing the scalability of your servers. For XMPP Tsung can test authentication, logins, chats, requests and much more.
Refer to http://tsung.erlang-projects.org/ for full details.
For initial install load Tsung on one client machine using the instructions below. The same tsung test can be run from multiple clients simultaneously in order to offer maximum stress testing.
1. wget http://tsung.erlang-projects.org/dist/tsung-1.3.3.tar.gz
2. extract the contents, e.g. to usr/local/share/tsung on ubuntu
3. run ./configure from inside the the tsung-1.3.3 folder
then make
make install
4. Run tsung from command prompt, the following should be displayed:
Usage: tsung start|stop|debug|status
Options:
-f set configuration file (default is ~/.tsung/tsung.xml)
-l set log file (default is ~/.tsung/log/YYYYMMDD-HH:MM/tsung.log)
-i set controller id (default is empty)
-r set remote connector (default is ssh)
-s enable erlang smp on client nodes
-F use long names (FQDN) for erlang nodes
-v print version information and exit
-h display this help and exit
You can simulate logins in a number of different way; for my benchmark test I initially created thousands of users within ejabberd using the following script:
for i in `seq 1 10000`; do echo $i && ejabberdctl register test$i servername password$i; done
This created 10000 users from test1 to test10000 with respective passwords.
These users can then be simulated by modifying the tsung.xml file usually located in ~/.tsung . Sample files for different test purposes are available at /usr/local/share/doc/tsung/examples/ .
Configure this file to match whatever benchmarking criteria you require; whether it be load progressions or test duration, all these values can be specified here.
Full explanation of file structure is available in the tsung user manual.
The file I used is similar to those in the samples, it made all users appear online simultaneously.
Some snippets from the tsung.xml file I used:
<clients>
<client host="localhost" use_controller_vm="true" maxusers="100000"></client>
</clients>
<servers>
<server host="serverIP" port="5222" type="tcp"></server>
</servers>
<load>
<arrivalphase phase="1" duration="1" unit="minute">
<users maxnumber="10000" interarrival="0.001" unit="second"></users>
</arrivalphase>
</load>
<options>
<option type="ts_jabber" name="global_number" value="10000"></option>
<option type="ts_jabber" name="userid_max" value="100000"></option>
<option type="ts_jabber" name="domain" value="server domain"></option>
<option type="ts_jabber" name="username" value="test"></option>
<option type="ts_jabber" name="passwd" value="password"></option>
</options>
<sessions>
<session probability="100" name="jabber-example" type="ts_jabber"
<request>
<jabber type="connect" ack="local"></jabber>
</request>
<thinktime value="2"></thinktime>
<transaction name="authenticate">
<request> <jabber type="auth_get" ack="local"></jabber></request>
<request> <jabber type="auth_set_plain" ack="local"></jabber></request>
</transaction>
<request>
<jabber type="presence:initial" ack="global"></jabber></request>
<thinktime value="6000"></thinktime>
<transaction name="close">
<request> <jabber type="close" ack="local"></jabber></request>
</transaction>
</session>
</sessions>
</tsung>
</tsung>
To run the test execute tsung -f tsung.xml start . Ensuring tsung.xml points to your own configuration file.
N.B If you are testing large number of users you need to look at changing max values in /opt/ejabberd/conf/ejabberdctl.cfg on the server instance. There are a number of options that can be set here, the file explains what each value does.
See results and witness logons by accessing http://MYSERVER:5280/admin and viewing log files in ~/.tsung/log
Refer to Tsung User manual for full usage
Support posts and archives http://lists.jabber.ru/pipermail/ejabberd/
Tsung is another open source tool written in erlang. Tsung can be used to load test on multiple protocols, including HTTP, LDAP, PostgreSQL and Jabber/XMPP servers.
Tsung can be used to simulate real users and log them all in simultaneously, stress testing the scalability of your servers. For XMPP Tsung can test authentication, logins, chats, requests and much more.
Refer to http://tsung.erlang-projects.org/ for full details.
For initial install load Tsung on one client machine using the instructions below. The same tsung test can be run from multiple clients simultaneously in order to offer maximum stress testing.
1. wget http://tsung.erlang-projects.org/dist/tsung-1.3.3.tar.gz
2. extract the contents, e.g. to usr/local/share/tsung on ubuntu
3. run ./configure from inside the the tsung-1.3.3 folder
then make
make install
4. Run tsung from command prompt, the following should be displayed:
Usage: tsung
Options:
-f
-l
-i
-r
-s enable erlang smp on client nodes
-F use long names (FQDN) for erlang nodes
-v print version information and exit
-h display this help and exit
You can simulate logins in a number of different way; for my benchmark test I initially created thousands of users within ejabberd using the following script:
for i in `seq 1 10000`; do echo $i && ejabberdctl register test$i servername password$i; done
This created 10000 users from test1 to test10000 with respective passwords.
These users can then be simulated by modifying the tsung.xml file usually located in ~/.tsung . Sample files for different test purposes are available at /usr/local/share/doc/tsung/examples/ .
Configure this file to match whatever benchmarking criteria you require; whether it be load progressions or test duration, all these values can be specified here.
Full explanation of file structure is available in the tsung user manual.
The file I used is similar to those in the samples, it made all users appear online simultaneously.
Some snippets from the tsung.xml file I used:
<clients>
<client host="localhost" use_controller_vm="true" maxusers="100000"></client>
</clients>
<servers>
<server host="serverIP" port="5222" type="tcp"></server>
</servers>
<load>
<arrivalphase phase="1" duration="1" unit="minute">
<users maxnumber="10000" interarrival="0.001" unit="second"></users>
</arrivalphase>
</load>
<options>
<option type="ts_jabber" name="global_number" value="10000"></option>
<option type="ts_jabber" name="userid_max" value="100000"></option>
<option type="ts_jabber" name="domain" value="server domain"></option>
<option type="ts_jabber" name="username" value="test"></option>
<option type="ts_jabber" name="passwd" value="password"></option>
</options>
<sessions>
<session probability="100" name="jabber-example" type="ts_jabber"
<request>
<jabber type="connect" ack="local"></jabber>
</request>
<thinktime value="2"></thinktime>
<transaction name="authenticate">
<request> <jabber type="auth_get" ack="local"></jabber></request>
<request> <jabber type="auth_set_plain" ack="local"></jabber></request>
</transaction>
<request>
<jabber type="presence:initial" ack="global"></jabber></request>
<thinktime value="6000"></thinktime>
<transaction name="close">
<request> <jabber type="close" ack="local"></jabber></request>
</transaction>
</session>
</sessions>
</tsung>
</tsung>
To run the test execute tsung -f tsung.xml start . Ensuring tsung.xml points to your own configuration file.
N.B If you are testing large number of users you need to look at changing max values in /opt/ejabberd/conf/ejabberdctl.cfg on the server instance. There are a number of options that can be set here, the file explains what each value does.
See results and witness logons by accessing http://MYSERVER:5280/admin and viewing log files in ~/.tsung/log
Refer to Tsung User manual for full usage
Support posts and archives http://lists.jabber.ru/pipermail/ejabberd/
Labels:
Ejabberd,
erlang,
jabber,
load test,
performance,
stress test,
tsung,
xmpp
Subscribe to:
Posts (Atom)