1 package org.opensrf.net.xmpp;
4 import java.net.Socket;
8 * Represents a single XMPP session. Sessions are responsible for writing to
9 * the stream and for managing a stream reader.
11 public class XMPPSession {
13 /** Initial jabber message */
14 public static final String JABBER_CONNECT =
15 "<stream:stream to='%s' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>";
17 /** Basic auth message */
18 public static final String JABBER_BASIC_AUTH =
19 "<iq id='123' type='set'><query xmlns='jabber:iq:auth'>" +
20 "<username>%s</username><password>%s</password><resource>%s</resource></query></iq>";
26 /** jabber username */
27 private String username;
28 /** jabber password */
29 private String password;
30 /** jabber resource */
31 private String resource;
33 /** XMPP stream reader */
35 /** Fprint-capable socket writer */
37 /** Raw socket output stream */
38 OutputStream outStream;
43 * Creates a new session.
44 * @param host The jabber domain
45 * @param port The jabber port
47 public XMPPSession( String host, int port ) {
53 /** true if this session is connected to the server */
54 public boolean connected() {
57 reader.getXMPPStreamState() == XMPPReader.XMPPStreamState.CONNECTED);
62 * Connects to the network.
63 * @param username The jabber username
64 * @param password The jabber password
65 * @param resource The Jabber resource
67 public void connect(String username, String password, String resource) throws XMPPException {
69 this.username = username;
70 this.password = password;
71 this.resource = resource;
76 /* open the socket and associated streams */
77 socket = new Socket(host, port);
79 /** the session maintains control over the output stream */
80 outStream = socket.getOutputStream();
81 writer = new PrintWriter(outStream, true);
83 /** pass the input stream to the reader */
84 reader = new XMPPReader(socket.getInputStream());
86 } catch(IOException ioe) {
88 XMPPException("unable to communicate with host " + host + " on port " + port);
91 /* build the reader thread */
92 Thread thread = new Thread(reader);
93 thread.setDaemon(true);
96 /* send the initial jabber message */
98 reader.waitCoreEvent(10000);
99 if( reader.getXMPPStreamState() != XMPPReader.XMPPStreamState.CONNECT_RECV )
100 throw new XMPPException("unable to connect to jabber server");
102 /* send the basic auth message */
103 sendBasicAuth(); /* XXX add support for other auth mechanisms */
104 reader.waitCoreEvent(10000);
106 throw new XMPPException("Authentication failed");
109 /** Sends the initial jabber message */
110 private void sendConnect() {
111 writer.printf(JABBER_CONNECT, host);
112 reader.setXMPPStreamState(XMPPReader.XMPPStreamState.CONNECT_SENT);
115 /** Send the basic auth message */
116 private void sendBasicAuth() {
117 writer.printf(JABBER_BASIC_AUTH, username, password, resource);
118 reader.setXMPPStreamState(XMPPReader.XMPPStreamState.AUTH_SENT);
123 * Sends an XMPPMessage.
124 * @param msg The message to send.
126 public void send(XMPPMessage msg) throws XMPPException {
129 outStream.write(msg.toXML().getBytes());
130 } catch (Exception e) {
131 throw new XMPPException(e.toString());
137 * @throws XMPPException if we are no longer connected.
139 private void checkConnected() throws XMPPException {
141 throw new XMPPException("Disconnected stream");
146 * Receives messages from the network.
147 * @param timeout Maximum number of milliseconds to wait for a message to arrive.
148 * If timeout is negative, this method will wait indefinitely.
149 * If timeout is 0, this method will not block at all, but will return a
150 * message if there is already a message available.
152 public XMPPMessage recv(int timeout) throws XMPPException {
158 while(true) { /* wait indefinitely for a message to arrive */
159 reader.waitCoreEvent(timeout);
160 msg = reader.popMessageQueue();
161 if( msg != null ) return msg;
167 while(timeout >= 0) { /* wait at most 'timeout' milleseconds for a message to arrive */
168 timeout -= reader.waitCoreEvent(timeout);
169 msg = reader.popMessageQueue();
170 if( msg != null ) return msg;