I. Overview of the SMACK Library
Smack is an open-source, easy-to-use Xmpp/jabber client library that is developed in the Java language and developed by Jive Software.
The advantage of smack is that programming is simple.
Smack's disadvantage is that its API is not designed for a large number of concurrent users, each customer needs 1 threads, occupy a relatively high resource, so when using smack for simulation testing, 1 machines can only simulate a limited (thousands of) customers.
As of November 27, 2014, the Smack Library has been developed to 4.0. Version 6.
The latest good news is that smack will support the Android system directly after the 4.1.0 release, without the need to use the previous smack ported Asmack library.
Smack Library source is hosted on GitHub, home see: https://github.com/igniterealtime/Smack/
Ii. Changes in Smack 4
Smack Library from 3.4 to 4.0.x version, its API has a large change, mainly:
1. Rename the connection class to Xmppconnection class
The Xmppconnection class is the parent class of the Xmpptcpconnection class and the Xmppboshconnection class.
2, the various provider class has been subcontracting
3. Keep-alive (persistent connection) mechanism moved from the Smack-core library to the Smack-extensions library
The keep-alive mechanism is now provided by the Pingmanager class.
4. The ToString () method of the Privacylist class is renamed to GetName ()
5. When all references to the chat instance are removed, the Chat.close () method should be called
Otherwise, the chat object will have a hidden memory leak, until the Chatmanager object is reclaimed by the garbage collector and the memory leaks are hidden.
6, Servertrustmanager class was removed
If you want to use XMPP with SSL authentication, you only need to provide your own Sslcontext object to the Connectionconfiguration object.
7, Packet.setproperty () moved from the Smack-core library to the Smack-extensions library
Its API can now be found in the Org.jivesoftware.smackx.jiveproperties package.
8. Connection.getaccountmanager () method is now changed to Accountmanager.getinstance (Xmppconnection) method
9, the exception API has been improved
10, Tocontains filter was removed
The characteristics of Smack library
1. Extremely easy to use, powerful API
Sending a text message to a user requires only a few lines of code:
[Java] view Plaincopyprint?
Abstractxmppconnection connection = new xmpptcpconnection ("Mtucker", "password", " Jabber.org ");
Connection.connect ();
Connection.login ();
Chat chat = chatmanager.getinstancefor (connection)
. Createchat ("[email protected]", new MessageListener () {
Public void ProcessMessage (chat chat, message message) {
System.out.println ("Received message:" + message);
}
});
Chat.sendmessage ("howdy!");
2, isolated the complexity of the underlying packet assembly, naturally have a corresponding library to complete these functions. Smack provides more intelligent high-level constructs such as the chat class and the roster class, which makes development more efficient.
1) There is no need to familiarize yourself with the XML format of XMPP, or even to understand XML
2) provides a simple communication
Smack allows developers to set a large number of properties for each message, which can also contain Java objects.
3) Open source code based on Apache license, which means you can put smack into your own business software.
Iv. composition of the Smack library
The smack library can be embedded into any Java application. The Smack library is composed of several jar files and is very flexible.
1, Smack-core.jar
Provides the core XMPP functionality. Are XMPP attributes that are defined by the XMPP RFC specification.
2, Smack-extensions.jar
Supports many of the extended (XEP) features defined by the XMPP Standards Foundation. This includes group chat, file transfer, user search, and more.
Later, you can view the documentation extension Guide:
Https://github.com/igniterealtime/Smack/blob/master/documentation/extensions/index.html
(Currently invalid)
3, Smack-experimental.jar
Supports many of the experiential (XEP) features defined by the XMPP Standards Foundation. Its API and functionality are considered to be unstable.
4, Smack-legacy.jar
Supports many legacy (XEP) features defined by the XMPP Standards Foundation.
5, Smack-bosh.jar
Supports Bosh communication (defined by the XEP-0124 specification). This code is considered to be in the beta phase.
6, Smack-jingle.jar
Support Jingle. This code is very old and is currently in a state of no maintenance.
7, Smack-resolver-dnsjava.jar
Supports parsing of DNS SRV records, primarily for platforms that do not support the Javax.naming API.
8, Smack-debug.jar
Enhanced GUI debugger for protocol traffic. When debug mode is turned on, it is automatically used if it is under the classpath.
You can view the document debug mode later:
Https://github.com/igniterealtime/Smack/blob/master/documentation/debugging.html
(Currently invalid)
v. Configuration of Smack
The initialization process for smack involves a 2-phase invocation.
1. Initialize System Properties
All system accessible properties are initialized through the Smackconfiguration class, and these properties are retrieved from the property value by means of the GetXXX method.
2. Initialize Startup class
Any class that inherits the Smackinitializer interface can be initialized after calling the Initialize () method, which means that the class that gets initialized is active after it is started.
If the Smackinitializer interface is not inherited, the initialization must be done by placing a static block of code that is executed automatically when the class is loaded.
Initialization is done through a configuration file. By default, smack loads the configuration file embedded in the Smack jar file (it is located in Org.jivesoftware.smack/smack-config.xml). This specified configuration file contains a list of classes that need to be loaded into the initialization. All classes of the manager type need to be initialized, and these manager classes are included in the initialization list described above.
Vi. examples of establishing connections
The Xmppconnection class is used to create a connection to the XMPP server, with the following code examples:
[Java] view Plaincopyprint?
//Create a connection to the jabber.org server
Abstractxmppconnection conn1 = new xmpptcpconnection ("username", "password", " Jabber.org ");
Conn1.connect ();
[Java] view Plaincopyprint?
-
// Create a connection to the specified port on the jabber.org server
-
Xmpptcpconnectionconfiguration config = xmpptcpconnectionconfiguration.builder ()
-
.setusernameandpassword ( "username" , "password" )
-
.setservicename ( "jabber.org" )
-
.sethost ( "earl.jabber.org" )
-
.setport (" 8222 ")
-
.build ();
-
abstractxmppconnection conn2 = New xmpptcpconnection (config);
-
Conn2.connect ();
Note that when you connect to an XMPP server, the default settings are used to maximize security, including applications for TLS encryption. The Connectionconfiguration class has advanced control over the connections created, such as the ability to turn encryption on or off.
You can view the document "Xmppconnection Management" later:
Https://github.com/igniterealtime/Smack/blob/master/documentation/connections.html
(Currently invalid)
Once you have created a connection, you should call the Xmppconnection.login () method to log on to the server. Once you're signed in, you can start chatting with other users by creating a Chat object or Groupchat object.
Vii. Use of Roster (list)
Roster is used to track whether other users are online. Users ' contacts can be organized in groups, such as "Friends", "colleagues". You can then see if each user in the group is online.
To retrieve roster, use the Xmppconnection.getroster () method. The Roster class allows you to find all the roster entities, and which group they belong to, and the current online status of each entity.
Viii. reading and writing packet (packet)
Each message sent from the client to the XMPP server is called a packet (packet). The Org.jivesoftware.smack.packet library contains encapsulated classes of three different basic packet types supported by XMPP (message messages, online status presence, IQ). Classes like chat or groupchat provide a higher-level structure to manage the automatic creation and delivery of packets. However, developers can also create and send packets directly.
The following code is to modify your online status so that others know you are not online.
[Java] view Plaincopyprint?
//Create new Online status object and set offline status
Presence presence = new presence (Presence.Type.unavailable);
Presence.setstatus ("Gone fishing");
//Send packet (assuming we already have a connection instance of Xmppconnection con
Con.sendpacket (presence);
Smack provides two ways to read incoming packets: Packetlistener (Packet listener) and Packetcollector (packet collector).
Both use the Packetfilter instance to determine which packet should be processed.
Packetlistener (packet listener) is used for event-style programming, while the Packetcollector (packet collector) has a result queue for a packet, and you can do the polling or blocking operations.
That is, if you want to perform some action when the packet arrives, the packet listener is a good fit. If you want to wait for the specified packet to arrive, then the package collector is a good fit.
Both the package collector and the package listener are created using the connection connection instance.
Third, xmppconnection management1. Create a connection
The Org.jivesoftware.smack.XMPPConnection class manages the connection to the XMPP server, and its default connection implementation class is org.jivesoftware.smack.XMPPTCPConnection. It mainly uses two construction methods,
One is the Xmpptcpconnection (Stringservername) method, and the parameter is the server name. The connection uses all the default settings, which are:
1) Execute the DNSSRV query to find the exact address and port (usually 5222) of the server.
2) Negotiate the maximum number of security with the server, including TLS encryption. However, if necessary, the connection will fall back to a lower security setting.
3) The XMPP resource name "Smack" will be used for the connection.
The second one is the Xmpptcpconnection (CONNECTIONCONFIGURATIONCC) constructor, which specifies advanced connection settings. These include:
1) Manually specify the server address and port instead of the DNSSRV query.
2) can turn on the connection compression.
3) Specify a custom connection resource name (such as work or home). A user must have a unique resource name for each connection to the server. For example, for the user "[email protected]", the full address with the resource should be "[email protected]/smack". By carrying a unique resource name, users can log on to the same server from different locations at the same time, which is true for multi-device scenarios.
The online priority value used for each resource: A message that determines which of the specified connections with resources to receive the bare address "[email protected]".
2. Connect and close the connection
To create a configuration for a new connection
Connectionconfigurationconfig = new Connectionconfiguration ("jabber.org", 5222);
Abstractxmppconnectionconn = new xmpptcpconnection (config);
Connect to Server
Conn.connect ();
Log on to the server
Conn.login ("username", "password", "Someresource");
...
Close connection
Conn.disconnect ();
By default, smack attempts to rebuild the connection once the connection is broken.
Use the setreconnectionallowed (Boolean) method of the Connectionconfiguration class to turn on or off the ability to re-connect.
The re-connect manager immediately tries to re-connect to the server, and it increases the latency setting to increase the success rate of the re-connection.
When the reconnection manager is waiting for the next reconnection, if you want to force reconnection, you can use the Connect () method of the Abstractxmppconnection class, which tries to establish a new connection. If the manual attempt also fails, the re-connect manager will continue to re-connect the work.
Iv. using Chat message communication
Sending and receiving messages back and forth is the core function of instant Messaging. Although a single message is sent and received in the form of a packet, it is usually treated as a message string for chatting, using the Org.jivesoftware.smack.Chat class.
1. Chat class
One chat chat creates a message thread (through the thread ID) between two users. The following code snippet shows how to create a new chat and then send a text message to the user:
Suppose you have created a xmppconnection named "Connection"
Chatmanagerchatmanager = Connection.getchatmanager ();
Chatnewchat = Chatmanager.createchat ("[Email protected]", Newmessagelistener () {
public void ProcessMessage (Chat chat,message Message) {
System.out.println ("Receivedmessage:" + message);
}
});
try{
Newchat.sendmessage ("howdy!");
}catch (Xmppexceptione) {
System.out.println ("Error deliveringblock");
}
The Chat.sendmessage (string) method makes it easy to create a message object, set the message body body with a string parameter, and then send a message. In some cases you may want to set additional values before sending messages, using the Chat.createmessage () method and the Chat.sendmessage (message) method, as shown in the following code snippet:
Messagenewmessage = new Message ();
Newmessage.setbody ("howdy!");
Message.setproperty ("FavoriteColor", "Red");
Newchat.sendmessage (Newmessage);
In the previous example, we can notice that a message listener MessageListener is specified when chatting chat is created, and the message listener is notified at any time when a chat message from another user arrives. The following code snippet uses a listener to make a parrot, which echoes messages that are passed from other users.
Suppose a message listener has been set up in chat chats MessageListener
Publicvoid ProcessMessage (chat chat, message message) {
Send the message content sent by the user to the user
Chat.sendmessage (Message.getbody ());
}
2. Call Chat
When you are prompted to have another user's chat message come up, the settings are slightly different because you are receiving a chat message for the first time. Instead of explicitly creating a chat to send a message, when Chatmanager creates a chat instance, you need to register to process the newly created chat instance. Chatmanager will find a matching chat through the thread ID, and if chat does not exist, it will create a new chat object to match. To get this new chat, you must register to be notified. You can register a message listener to receive all incoming messages.
Assume that a xmppconnection named "Connection" has been created
CHATMANAGERCM = Connection.getchatmanager (). Addchatlistener (New Chatmanagerlistener () {
@Override
public void chatcreated (chat chat, booleancreatedlocally) {
if (!createdlocally)
Chat.addmessagelistener (Newmynewmessagelistener ());
}
});
In addition to thread-based chat messages, there are some clients that do not send thread IDs as part of chat. To handle this situation, smack attempts to match the received message to the closest match to the existing chat based on Jid. It tries to find chat with the full jid, and if it doesn't, try using the basic Jid to find chat. If no existing chat is found to match, a new chat is created.
V. List roster and online status presence
Lists allow you to track whether other users are online, and lists allow you to organize users into groups, such as friends or working groups. Other instant Messaging IM systems treat list roster as friends list, contact list, and so on.
1. List entries
Each user in the list is represented by Rosterentry, which includes:
1) an XMPP address (e.g. "[email protected]")
2) The name of the note you wrote for the user (e.g. "Joe")
3) List of groups in the list. If the list of entries does not belong to any group, then it is called "Unfiledentry".
The following code snippet prints all the entries in the list:
Rosterroster = Connection.getroster ();
Collection<rosterentry>entries = Roster.getentries ();
for (rosterentryentry:entries) {
SYSTEM.OUT.PRINTLN (entry);
}
There is also a way to get a single entry, get the "Unfiledentry" method, and get a method of a group or all groups.
2. Online Status
Each entry in the list has an online status associated with it. The Roster.getpresence (Stringuser) method returns a Presence object that represents whether the user is online or is empty. Null is the return you have not subscribed to whether the user is online.
Note: In general, subscriptions to online status are always bound to users in the list, but this does not fit in all cases.
The online status of a user is either online or offline. When users are online, their online presence can also include extended information, such as what the user is doing, whether the user is willing to be disturbed, and so on. Refer to the presence class for details.
3. Change of listening list roster and online status presence
A typical scenario for the roster class is to display the user group and list in a tree structure, and the user list contains the status of whether the user is online. For example, refer to the roster of a EXODUSXMPP client as shown.
Information about the status of the online may change frequently, and roster entries may often be modified or deleted. To monitor changes in roster and presence data, you should use Rosterlistener. To get all the reminders for roster changes, you must register Rosterlistener before logging in to the XMPP server. The following code fragment registers a roster rosterlistener that can print any presence changes in the standard output. A standard client can use similar code to update the roster interface with changing information.
Rosterroster = Con.getroster ();
Roster.addrosterlistener (Newrosterlistener () {
Ignore event public void entriesadded (collection<string> addresses) {}
public void entriesdeleted (collection<string>addresses) {}
Public voidentriesupdated (collection<string> addresses) {}
public void presencechanged (presencepresence) {
System.out.println ("presencechanged:" + presence.getfrom () + "" + presence);
}
});
4. Add entries to roster
Roster and presence use a permissions-based model, and users must be licensed by others to add these people to roster. This protects the user's privacy and ensures that only approved users can see their presence information. So, when you want to add a user to your roster, you have to get the user to accept your request.
If a user requests to subscribe to your online status presence, the user must first add you to his roster, so he will initiate the request and you must choose to accept or reject the request. Smack handles booking requests for presence in the following three ways:
1) automatic acceptance of all presence booking requests
2) automatic rejection of all presence booking requests
3) manual processing of each presence booking request
There are three ways to set the processing of requests through the Roster.setsubscriptionmode (Intsubscriptionmode) method. Simple clients typically use the first automatic way to process a booking request, while a fully functional client should choose the third way to manually process the request, letting the end user decide whether to accept the request or reject it. If you use manual mode, you should register a packetlistener to listen for the Presence.Type.SUBSCRIBE type of presence package.
XMPP Client library Smack One of the development of version 4.0.6