Babbler is a young XMPP client library for Java SE 8 based on JAXB as XML processing technology.
It aims to provide good JavaDoc documentation, clean code, an easy to use API and a high level of software quality ( which is currently ensured by 700+ unit tests).
It supports the core specifications RFC 6120 , RFC 6121, RFC 7622, as well as many extensions.
Since this project is quite young, the API might change. Comments on the API are appreciated.
|
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Blog | blog.xmpp.rocks
| | Documentation | docs.xmpp.rocks
| | Mailing List | groups.xmpp.rocks
| | Latest Version in Maven Central
|
| | License
|
|
<dependency>
<groupId>rocks.xmpp</groupId>
<artifactId>xmpp-core-client</artifactId>
<version>0.8.2</version>
</dependency>
<dependency>
<groupId>rocks.xmpp</groupId>
<artifactId>xmpp-extensions-client</artifactId>
<version>0.8.2</version>
</dependency>
Development snapshots are available on OSS Sonatype nexus:
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependency>
<groupId>rocks.xmpp</groupId>
<artifactId>xmpp-core-client</artifactId>
<version>0.9.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>rocks.xmpp</groupId>
<artifactId>xmpp-extensions-client</artifactId>
<version>0.9.0-SNAPSHOT</version>
</dependency>
(Only listing historical and standard tracks extensions with status 'Draft' or 'Final' that are applicable to XMPP clients)
XEP-0004: Data Forms
XEP-0009: Jabber-RPC
XEP-0012: Last Activity
XEP-0013: Flexible Offline Message Retrieval
XEP-0016: Privacy Lists
XEP-0020: Feature Negotiation
XEP-0030: Service Discovery
XEP-0033: Extended Stanza Addressing
XEP-0045: Multi-User Chat
XEP-0047: In-Band Bytestreams
XEP-0048: Bookmarks
XEP-0049: Private XML Storage
XEP-0050: Ad-Hoc Commands
XEP-0054: vcard-temp
XEP-0055: Jabber Search
XEP-0059: Result Set Management
XEP-0060: Publish-Subscribe
XEP-0065: SOCKS5 Bytestreams
XEP-0066: Out of Band Data
XEP-0070: Verifying HTTP Requests via XMPP
XEP-0071: XHTML-IM
XEP-0072: SOAP Over XMPP
XEP-0077: In-Band Registration
XEP-0079: Advanced Message Processing
XEP-0080: User Location
XEP-0084: User Avatar
XEP-0085: Chat State Notifications
XEP-0092: Software Version
XEP-0095: Stream Initiation
XEP-0096: SI File Transfer
XEP-0106: JID Escaping
XEP-0107: User Mood
XEP-0108: User Activity
XEP-0114: Jabber Component Protocol
XEP-0115: Entity Capabilities
XEP-0118: User Tune
XEP-0122: Data Forms Validation
XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)
XEP-0131: Stanza Headers and Internet Metadata
XEP-0136: Message Archiving
XEP-0137: Publishing Stream Initiation Requests
XEP-0138: Stream Compression
XEP-0141: Data Forms Layout
XEP-0144: Roster Item Exchange
XEP-0145: Annotations
XEP-0152: Reachability Addresses
XEP-0153: vCard-Based Avatars
XEP-0155: Stanza Session Negotiation
XEP-0156: Discovering Alternative XMPP Connection Methods
XEP-0158: CAPTCHA Forms
XEP-0163: Personal Eventing Protocol
XEP-0166: Jingle
XEP-0167: Jingle RTP Sessions
XEP-0171: Language Translation
XEP-0172: User Nickname
XEP-0174: Serverless Messaging
XEP-0176: Jingle ICE-UDP Transport Method
XEP-0177: Jingle Raw UDP Transport Method
XEP-0184: Message Delivery Receipts
XEP-0191: Blocking Command
XEP-0198: Stream Management
XEP-0199: XMPP Ping
XEP-0202: Entity Time
XEP-0203: Delayed Delivery
XEP-0206: XMPP Over BOSH
XEP-0221: Data Forms Media Element
XEP-0224: Attention
XEP-0229: Stream Compression with LZW
XEP-0231: Bits of Binary
XEP-0249: Direct MUC Invitations
XEP-0256: Last Activity in Presence
XEP-0258: Security Labels in XMPP
XEP-0260: Jingle SOCKS5 Bytestreams Transport Method
XEP-0261: Jingle In-Band Bytestreams Transport Method
XEP-0262: Use of ZRTP in Jingle RTP Sessions
XEP-0266: Codecs for Jingle Audio
XEP-0297: Stanza Forwarding
XEP-0300: Use of Cryptographic Hash Functions in XMPP
XEP-0301: In-Band Real Time Text
XEP-0308: Last Message Correction
XEP-0319: Last User Interaction in Presence
XEP-0368: SRV records for XMPP over TLS
XEP-0410: MUC Self-Ping (Schrödinger's Chat)
Supported experimental XEPs:
Additionally following informational XEP documents are respected:
XEP-0068: Field Standardization for Data Forms
XEP-0082: XMPP Date and Time Profiles
XEP-0083: Nested Roster Groups
XEP-0126: Invisibility
XEP-0128: Service Discovery Extensions
XEP-0149: Time Periods
XEP-0170: Recommended Order of Stream Feature Negotiation
XEP-0175: Best Practices for Use of SASL ANONYMOUS
XEP-0201: Best Practices for Message Threads
XEP-0205: Best Practices to Discourage Denial of Service Attacks
XEP-0222: Persistent Storage of Public Data via PubSub
XEP-0223: Persistent Storage of Private Data via PubSub
This project is licensed under MIT License.
The first thing you want to do in order to connect to an XMPP server is creating a XmppClient
object:
XmppClient xmppClient = XmppClient.create("domain");
The XmppClient
instance is the central object. Every other action you will do revolves around this instance (e.g.
sending and receiving messages).
A session to an XMPP server can be established in three ways (connection methods):
- By a normal TCP socket connection
- By a BOSH connection (XEP-0124)
- By a WebSocket connection (RFC 7395)
By default, the XmppClient
will try to establish a connection via TCP first during the connection process. If the
connection fails, it will try to discover alternative connection methods and try to connect with one of them (usually
BOSH). The hostname and port is determined by doing a DNS lookup.
You can also configure different connection methods manually (e.g. if you want to use another port or want to use a proxy).
In order to create immutable and reusable configuration objects (which could be reused by multiple sessions) and to avoid huge constructors, the Builder Pattern is used to create custom configurations:
TcpConnectionConfiguration tcpConfiguration = TcpConnectionConfiguration.builder()
.hostname("localhost")
.port(5222)
.build();
Here's another example how to configure a BOSH connection (which would connect to the
URL http://domain:5280/http-bind/
over a HTTP proxy server):
BoshConnectionConfiguration boshConfiguration = BoshConnectionConfiguration.builder()
.hostname("domain")
.port(5280)
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("hostname", 3128)))
.path("/http-bind/")
.build();
And this is how you would configure a WebSocket connection to wss://host:7443/ws
(requires xmpp-websocket
dependency):
WebSocketConnectionConfiguration webSocketConfiguration = WebSocketConnectionConfiguration.builder()
.hostname("host")
.port(7443)
.path("/ws/")
.sslContext(sslContext)
.channelEncryption(ChannelEncryption.DIRECT)
.build();
Now let's pass them to the session to tell it that it should use them:
XmppClient xmppClient = XmppClient.create("domain", tcpConfiguration, boshConfiguration);
During connecting, the session will try all configured connections in order, until a connection is established.
You can set a custom SSLContext
by configuring it like this:
TcpConnectionConfiguration tcpConfiguration = TcpConnectionConfiguration.builder()
.channelEncryption(ChannelEncryption.OPTIONAL)
.sslContext(sslContext)
.hostnameVerifier(hostnameVerifier)
.build();
Note that the use of a custom HostnameVerifier
is possible but not recommended in most cases, since the built-in logic
to verify the host name does a good job.
Before connecting to a server, you should configure your XMPP session.
You might want to do one of the following:
- Adding event listeners in order to listen for inbound messages, roster and presence changes or to modify outbound messages.
- Setting up a custom SSL context
- Configuring extensions, e.g.
- Enable or disable certain extensions
- Setting an identity for the connection (Service Discovery)
- etc.
Here are some examples:
// Listen for presence changes
xmppClient.addInboundPresenceListener(e -> {
// Handle inbound presence.
});
// Listen for messages
xmppClient.addInboundMessageListener(e -> {
// Handle inbound message
});
// Listen for roster pushes
xmppClient.getManager(RosterManager.class).addRosterListener(e -> {
});
If you have prepared your session, you are now ready to connect to the server:
try {
xmppClient.connect();
} catch (XmppException e) {
// ...
}
The session will try to connect to the XMPP server by using the configured connections in order.
Connecting involves opening the initial XMPP stream header and negotiate any features offered by the server (most likely only TLS).
After connecting, you have to authenticate and bind a resource, in order to become a "connected resource". Both steps are understood as "login":
try {
xmppClient.login("username", "password", "resource");
} catch (AuthenticationException e) {
// Login failed
}
Initial presence is sent automatically, so that you are now an "available resource" (you will appear online to your contacts) and can now start sending messages.
Sending a simple chat message works like this:
xmppClient.send(new Message(Jid.of("juliet@example.net"), Message.Type.CHAT));
If you want to change your presence availability, just send a new presence with a "show" value.
xmppClient.send(new Presence(Presence.Show.AWAY));
Closing a session is simply done with:
xmppClient.close();
Note, that XmppClient
implements java.lang.AutoCloseable
, which means you can also use the try-with-resources
statement, which automatically closes the session:
try (XmppClient xmppClient = XmppClient.create("domain")) {
xmppClient.connect();
} catch (XmppException e) {
// handle exception
}