一、新建maven工程,增加smack相关依赖。
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-core</artifactId>
<version>4.2.4</version>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-extensions</artifactId>
<version>4.2.4</version>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-tcp</artifactId>
<version>4.2.4</version>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-java7</artifactId>
<version>4.2.4</version>
</dependency
依赖中如果缺少smack-java7,那么在初始化XMPPTCPConnection时会报错空指针异常。
java.lang.NullPointerException
at org.jivesoftware.smack.util.stringencoder.Base64.encode(Base64.java:64)
at org.jivesoftware.smack.util.stringencoder.Base64.encode(Base64.java:60)
at org.jivesoftware.smack.util.stringencoder.Base64.encodeToString(Base64.java:42)
at org.jivesoftware.smackx.caps.EntityCapsManager.generateVerificationString(EntityCapsManager.java:724)
at org.jivesoftware.smackx.caps.EntityCapsManager.generateVerificationString(EntityCapsManager.java:591)
at org.jivesoftware.smackx.caps.EntityCapsManager.updateLocalEntityCaps(EntityCapsManager.java:487)
at org.jivesoftware.smackx.caps.EntityCapsManager.<init>(EntityCapsManager.java:315)
at org.jivesoftware.smackx.caps.EntityCapsManager.getInstanceFor(EntityCapsManager.java:378)
at org.jivesoftware.smackx.caps.EntityCapsManager$1.connectionCreated(EntityCapsManager.java:121)
at org.jivesoftware.smack.AbstractXMPPConnection.<init>(AbstractXMPPConnection.java:310)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.<init>(XMPPTCPConnection.java:308)
at com.xxx.smack.App.<clinit>(App.java:25)
二、编码,连接openfire服务器,登录,发送消息。
private static XMPPTCPConnectionConfiguration config;
private static AbstractXMPPConnection conn;
static {
try {
config = XMPPTCPConnectionConfiguration.builder()
.setXmppDomain("10.119.9.149")
.setHost("10.119.9.149")
.setPort(5222)
.setDebuggerEnabled(true)
.setSecurityMode(SecurityMode.disabled)
.build();
conn = new XMPPTCPConnection(config);
conn.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void login(String username,String password){
try {
if(conn!=null){
conn.login(username, password);
System.out.println("user "+username+" login successfully.");
}
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行登录方法,打印如下消息。
表明smack调用登录接口成功。
接下来,我们编写发送消息方法。
@SuppressWarnings("deprecation")
public static void sendMessage(String username,String password,String msg){
//先登录
login(username, password);
//再构建聊天室
ChatManager cm = ChatManager.getInstanceFor(conn);
cm.addListener(new IncomingChatMessageListener() {
@Override
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
System.out.println("message from : "+from+" : "+message.getBody());
}
});
try {
EntityBareJid jid = JidCreate.entityBareFrom("smack@10.119.9.149");
Chat chat = cm.chatWith(jid);
Message message = new Message();
message.setBody(msg);
chat.send(message);
while (true);
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
发送消息,需要先登录,这里调用上一步的登录方法,传入用户名密码,发送消息方法如果不做特殊处理,发送完成,方法推出,无法等到对方回复,这里做了一个简单的处理,利用while(true)做一个无限循环,等待对方回复消息。
这次单独运行sendMessage()方法,运行结果如下。
消息发送成功。另外,我们在spark客户端上可以看到smack用户收到了消息:
如果我们回复一个"笑脸"表情:
控制台收到的"笑脸"回复:
最后,附上完整代码:
package com.xxx.smack;
import java.io.IOException;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
public class App {
private static XMPPTCPConnectionConfiguration config;
private static AbstractXMPPConnection conn;
static {
try {
config = XMPPTCPConnectionConfiguration.builder()
.setXmppDomain("10.119.9.149")
.setHost("10.119.9.149")
.setPort(5222)
.setDebuggerEnabled(true)
.setSecurityMode(SecurityMode.disabled)
.build();
conn = new XMPPTCPConnection(config);
conn.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void login(String username,String password){
try {
if(conn!=null){
conn.login(username, password);
System.out.println("user "+username+" login successfully.");
}
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public static void sendMessage(String username,String password,String msg){
//先登录
login(username, password);
//再构建聊天室
ChatManager cm = ChatManager.getInstanceFor(conn);
cm.addListener(new IncomingChatMessageListener() {
@Override
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
System.out.println("message from : "+from+" : "+message.getBody());
}
});
try {
EntityBareJid jid = JidCreate.entityBareFrom("smack@10.119.9.149");
Chat chat = cm.chatWith(jid);
Message message = new Message();
message.setBody(msg);
chat.send(message);
while (true);
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main( String[] args ){
//login("hadoop", "hadoop");
sendMessage("hadoop", "hadoop", "hello,smack");
}
}
到这里,简单的调用smack和openfire服务器通信,并构建聊天过程就完成了。