实现群聊和单聊实际差不多,下面给出一个案例供不熟悉的朋友参考。
首先引用smack库(整体pom文件都给出好了)
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.5
com.nufront.xmpp
boot-xmpp-demo
0.0.1-SNAPSHOT
boot-xmpp-demo
boot-xmpp-demo
1.8
4.4.6
1.8
1.8
3.9.0
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-mongodb
org.springframework.boot
spring-boot-configuration-processor
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.igniterealtime.smack
smack-core
${smack-version}
org.igniterealtime.smack
smack-extensions
${smack-version}
org.igniterealtime.smack
smack-tcp
${smack-version}
org.igniterealtime.smack
smack-java8
${smack-version}
org.igniterealtime
rest-api-client
1.1.5
jakarta.validation
jakarta.validation-api
2.0.2
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
然后用两个用户登录tigase,并进入相同的房间,互发消息可以发现对方能收到
用户1
package com.nufront.xmpp.bootxmppdemo.muc.ssl;
import com.nufront.xmpp.bootxmppdemo.KXMPPAccountManager;
import lombok.extern.slf4j.Slf4j;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.EntityJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import javax.net.ssl.*;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
/**
* 群聊测试
*/
@Slf4j
public class MucTestA {
private static XMPPTCPConnectionConfiguration config;
private static AbstractXMPPConnection conn;
static {
try {
SSLContext ctx = SSLContext.getInstance("SSL");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(KXMPPAccountManager.class.getResourceAsStream("/tigase8.keystore"), "nufront@123".toCharArray());
tmf.init(tks);
ctx.init(null, tmf.getTrustManagers(), null);
config = XMPPTCPConnectionConfiguration.builder()
//host可使用外网
.setHost("192.168.43.51")
.setXmppDomain("ubuntu")
.setPort(5222)
.setSslContextFactory(() -> ctx)
.setSecurityMode(ConnectionConfiguration.SecurityMode.required)
.setResource("tcf")
.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
//不验证hostname是否正确
return true;
}
})
//信任自签证书,关键
.setCustomX509TrustManager(new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
})
.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 (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public static void sendMessage(String username, String password, String msg) throws Exception {
//先登录
login(username, password);
//进入房间
MultiUserChatManager mucCM = MultiUserChatManager.getInstanceFor(conn);
EntityBareJid roomJID = JidCreate.entityBareFrom("[email protected]");
MultiUserChat muc = mucCM.getMultiUserChat(roomJID);
//用户加入房间
muc.join(Resourcepart.from("tsung1"));
muc.sendMessage(msg + username);
//监听服务端的消息
conn.addAsyncStanzaListener(new StanzaListener() {
@Override
public void processStanza(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {
log.info("processStanza:{}", stanza.toXML());
//收到服务端回执则不需要重发消息
}
}, null);
//监听房间的消息
muc.addMessageListener(new MessageListener() {
@Override
public void processMessage(Message message) {
log.info("房间消息:{}", message);
}
});
muc.addParticipantListener(new PresenceListener() {
@Override
public void processPresence(Presence presence) {
log.info("presence消息:{}", presence);
}
});
//邀請监听
mucCM.addInvitationListener(new InvitationListener() {
@Override
public void invitationReceived(XMPPConnection conn, MultiUserChat room, EntityJid inviter, String reason, String password, Message message, MUCUser.Invite invitation) {
log.info("invitationReceived:conn:{},room:{},inviter:{},reason:{},passwd:{},message:{},invitation:{}",
conn, room, inviter, reason, password, message, invitation);
}
});
Thread.sleep(10 * 1000);
log.info("准备离开房间....");
muc.leave();
Thread.sleep(Integer.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
sendMessage("tsung1", "tsung1", "888,this is a test muc message from");
}
}
用户2
package com.nufront.xmpp.bootxmppdemo.muc.ssl;
import com.nufront.xmpp.bootxmppdemo.KXMPPAccountManager;
import lombok.extern.slf4j.Slf4j;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.EntityJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import javax.net.ssl.*;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
/**
* 群聊测试
*/
@Slf4j
public class MucTestB {
private static XMPPTCPConnectionConfiguration config;
private static AbstractXMPPConnection conn;
static {
try {
SSLContext ctx = SSLContext.getInstance("SSL");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(KXMPPAccountManager.class.getResourceAsStream("/tigase8.keystore"), "nufront@123".toCharArray());
tmf.init(tks);
ctx.init(null, tmf.getTrustManagers(), null);
config = XMPPTCPConnectionConfiguration.builder()
//host可使用外网
.setHost("192.168.43.51")
.setXmppDomain("ubuntu")
.setPort(5222)
.setSslContextFactory(() -> ctx)
.setSecurityMode(ConnectionConfiguration.SecurityMode.required)
.setResource("tcf")
.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
//不验证hostname是否正确
return true;
}
})
//信任自签证书,关键
.setCustomX509TrustManager(new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
})
.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 (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public static void sendMessage(String username, String password, String msg) throws Exception {
//先登录
login(username, password);
//进入房间
MultiUserChatManager mucCM = MultiUserChatManager.getInstanceFor(conn);
EntityBareJid roomJID = JidCreate.entityBareFrom("[email protected]");
MultiUserChat muc = mucCM.getMultiUserChat(roomJID);
//用户加入房间
muc.join(Resourcepart.from("tsung2"));
muc.sendMessage(msg + username);
//监听服务端的消息
conn.addAsyncStanzaListener(new StanzaListener() {
@Override
public void processStanza(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {
log.info("processStanza:{}", stanza.toXML());
//收到服务端回执则不需要重发消息
}
}, null);
//监听房间的消息
muc.addMessageListener(new MessageListener() {
@Override
public void processMessage(Message message) {
log.info("房间消息:{}", message);
}
});
muc.addParticipantListener(new PresenceListener() {
@Override
public void processPresence(Presence presence) {
log.info("presence消息:{}", presence);
}
});
//邀請监听
mucCM.addInvitationListener(new InvitationListener() {
@Override
public void invitationReceived(XMPPConnection conn, MultiUserChat room, EntityJid inviter, String reason, String password, Message message, MUCUser.Invite invitation) {
log.info("invitationReceived:conn:{},room:{},inviter:{},reason:{},passwd:{},message:{},invitation:{}",
conn, room, inviter, reason, password, message, invitation);
}
});
/* Thread.sleep(10 * 1000);
log.info("准备离开房间....");
muc.leave();*/
Thread.sleep(Integer.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
sendMessage("tsung2", "tsung2", "123,this is a test muc message from");
}
}
直接运行即可测试群聊进组、发消息、退群功能。