Openfire即時通訊服務搭建與Smack訪問
阿新 • • 發佈:2019-01-05
Openfire 是開源的、基於可拓展通訊和表示協議(XMPP)、採用Java程式語言開發的實時協作伺服器。 Openfire安裝和使用都非常簡單,並利用Web進行管理。單臺伺服器可支援上萬併發使用者。
首先到openfire官網上去下載Openfire的伺服器包與Smack的客戶端呼叫包。
開啟後在這裡可以看到有Openfire,Spark,Smack這三個東西,我簡單解釋一下它們分別是什麼,Openfire是跑在伺服器的,Spark與Smack是跑在客戶機上的,而Spark是已經構建好的應用程式,下載下來安裝即可使用(看下面的截圖),Smack是提供訪問Openfire的呼叫介面,就是做開發寫程式碼的啦。
Openfire下載後,如果是win的版本,那麼它是一個exe的安裝包,執行下一步下一步即可,其間會需要配置資料庫(Openfire當然是需要資料庫支援的了,比如要存帳號等等的資訊)。具體可以參照這個 http://jingyan.baidu.com/article/2c8c281df16ad30008252ae4.html
Openfire安裝成功後,下載Smack的包,裡邊包含有相應介面的jar包,匯入到我們的工程裡(不同版本的smack jar可能會不太一樣)
編寫我們的程式訪問Operfire
import java.util.Collection; import java.util.Iterator; import javax.net.SocketFactory; import org.jivesoftware.smack.AccountManager; import org.jivesoftware.smack.Chat; import org.jivesoftware.smack.ChatManager; import org.jivesoftware.smack.ChatManagerListener; import org.jivesoftware.smack.Connection; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.Message.Type; public class SmackUtil { private Connection connection; private ConnectionConfiguration config; /** openfire伺服器address */ private final static String server = "10.100.53.65"; private final void print(Object o) { if (o != null) { System.out.println(o); } } private final void print(Object o, Object... args) { if (o != null && args != null && args.length > 0) { String s = o.toString(); for (int i = 0; i < args.length; i++) { String item = args[i] == null ? "" : args[i].toString(); if (s.contains("{" + i + "}")) { s = s.replace("{" + i + "}", item); } else { s += " " + item; } } System.out.println(s); } } /** * 初始Smack對openfire伺服器連結的基本配置 */ public void init() { try { //connection = new XMPPConnection(server); //connection.connect(); /** 5222是openfire伺服器預設的通訊埠,你可以登入http://10.100.53.65:9090/到管理員控制檯檢視客戶端到伺服器埠 */ config = new ConnectionConfiguration(server, 5222); /** 是否啟用壓縮 */ config.setCompressionEnabled(true); /** 是否啟用安全驗證 */ config.setSASLAuthenticationEnabled(true); /** 是否啟用除錯 */ config.setDebuggerEnabled(false); config.setReconnectionAllowed(true); config.setRosterLoadedAtLogin(true); /** 建立connection連結 */ connection = new XMPPConnection(config); /** 建立連線 */ connection.connect(); System.out.println("connection success"); } catch (XMPPException e) { e.printStackTrace(); } print(connection); print(connection.getConnectionID()); } public void destory() { if (connection != null) { connection.disconnect(); connection = null; } } /** * ConnectionConfiguration 的基本配置相關資訊 */ public void seeConfig() { print("PKCS11Library: " + config.getPKCS11Library()); print("ServiceName: {0}", config.getServiceName()); // ssl證書密碼 print("TruststorePassword: {0}", config.getTruststorePassword()); print("TruststorePath: {0}", config.getTruststorePath()); print("TruststoreType: {0}", config.getTruststoreType()); SocketFactory socketFactory = config.getSocketFactory(); print("SocketFactory: {0}", socketFactory); } /** * Connection 基本方法資訊 */ public void seeConnection() { /** 使用者管理 */ AccountManager accountManager = connection.getAccountManager(); for (String attr : accountManager.getAccountAttributes()) { print("AccountAttribute: {0}", attr); } print("AccountInstructions: {0}", accountManager.getAccountInstructions()); /** 是否連結 */ print("isConnected:", connection.isConnected()); print("isAnonymous:", connection.isAnonymous()); /** 是否有許可權 */ print("isAuthenticated:", connection.isAuthenticated()); print("isSecureConnection:", connection.isSecureConnection()); /** 是否使用壓縮 */ print("isUsingCompression:", connection.isUsingCompression()); } /** * 建立使用者 * @param username * @param password */ public void createUser(String username, String password){ AccountManager accountManager = connection.getAccountManager(); try { /** 建立一個使用者;你可以在管理員控制檯頁面http://10.100.53.65:9090/user-summary.jsp檢視使用者/組的相關資訊,來檢視是否成功建立使用者 */ accountManager.createAccount(username, password); /** 修改密碼 */ accountManager.changePassword("abc"); } catch (XMPPException e) { e.printStackTrace(); } } /** * 修改密碼 * @param username * @param password */ public void changePassword(String password){ AccountManager accountManager = connection.getAccountManager(); try { /** 修改密碼 */ accountManager.changePassword("123456"); } catch (XMPPException e) { e.printStackTrace(); } } /** * 使用者登陸 * @param username * @param password */ public void login(String username, String password) { try { /** 使用者登陸,使用者名稱、密碼 */ connection.login(username, password); } catch (XMPPException e) { e.printStackTrace(); } /** 獲取當前登陸使用者 */ print("User:", connection.getUser()); /** 所有使用者組 */ Roster roster = connection.getRoster(); /* try { roster.createEntry("test55", "test55", null);//新增好友,不新增成為好友也同樣可以收發資訊 } catch (XMPPException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ /** 好友使用者組,你可以用Spark新增使用者好友,這樣這裡就可以查詢到相關的資料 */ Collection<RosterEntry> rosterEntiry = roster.getEntries(); Iterator<RosterEntry> iter = rosterEntiry.iterator(); while (iter.hasNext()) { RosterEntry entry = iter.next(); print("Groups: {0}, Name: {1}, Status: {2}, Type: {3}, User: {4}", entry.getGroups(), entry.getName(), entry.getStatus(), entry.getType(), entry); } print("-------------------------------"); /** 未處理、驗證好友,新增過的好友,沒有得到對方同意 */ Collection<RosterEntry> unfiledEntries = roster.getUnfiledEntries(); iter = unfiledEntries.iterator(); while (iter.hasNext()) { RosterEntry entry = iter.next(); print("Groups: {0}, Name: {1}, Status: {2}, Type: {3}, User: {4}", entry.getGroups(), entry.getName(), entry.getStatus(), entry.getType(), entry); } } /** * 新增訊息監聽器 */ public void addMsgListener(){ //監聽接收到的訊息 connection.getChatManager().addChatListener(new ChatManagerListener() { //可以監聽到所有使用者發來的訊息 @Override public void chatCreated(Chat chat, boolean createdLocally) { chat.addMessageListener(new MessageListener() { public void processMessage(Chat chat, Message message) { //String from = message.getFrom(); //String body = message.getBody(); System.out.println("body:"+message.getBody()); } }); } }); } /** * Packet訊息聊天 * @param from * @param to * @param msg */ public void sendPacketMsg(String from, String to, String msg) { // try { // connection.login(from, from); // } catch (XMPPException e) { // e.printStackTrace(); // } /** 更改使用者狀態,available=true表示線上,false表示離線,status狀態簽名;當你登陸後,在Spark客戶端軟體中就可以看到你登陸的狀態 */ Presence presence = new Presence(Presence.Type.available); presence.setStatus("Q我吧"); connection.sendPacket(presence); Session session = new Session(); //String sessid = session.nextID(); connection.sendPacket(session); Message message = new Message(to+"@" + server, Type.chat); //Message message = new Message(sessid, Type.chat); message.setBody(msg); connection.sendPacket(message); } /** * Chat訊息聊天 * @param from * @param to * @param msg */ public void sendChatMsg(String from, String to, String msg) { /** 設定狀態 */ // try { // connection.login(from, from); // } catch (XMPPException e) { // e.printStackTrace(); // } /** 設定狀態 */ Presence presence = new Presence(Presence.Type.available); presence.setStatus("Q我吧"); connection.sendPacket(presence); /** 獲取當前登陸使用者的聊天管理器 */ ChatManager chatManager = connection.getChatManager(); /** 為指定使用者建立一個chat,監聽對方發過來的訊息 */ Chat chat = chatManager.createChat(to+"@" + server, new MessageListener() {//僅監聽該使用者發來的訊息 @Override public void processMessage(Chat chat, Message message) { System.out.println("body:"+message.getBody()); } }); try { /** 傳送訊息 */ chat.sendMessage(msg); /** 用message物件傳送訊息 */ // Message message = new Message(); // message.setBody("message"); // message.setProperty("color", "red"); // chat.sendMessage(message); } catch (XMPPException e) { e.printStackTrace(); } } }
建立兩個通訊的測試帳號
public static void main(String[] args) {
SmackUtil smackUtil = new SmackUtil();
smackUtil.init();
smackUtil.seeConfig();
smackUtil.seeConnection();
smackUtil.createUser("test1", "test1");
}
public static void main(String[] args) { SmackUtil smackUtil = new SmackUtil(); smackUtil.init(); smackUtil.seeConfig(); smackUtil.seeConnection(); smackUtil.createUser("test2", "test2"); }
利用剛建立好的帳號來登陸併發送訊息
test1 登陸併發送訊息:
public static void main(String[] args) {
SmackUtil smackUtil = new SmackUtil();
smackUtil.init();
smackUtil.seeConfig();
smackUtil.seeConnection();
smackUtil.login("test1", "test1");
smackUtil.addMsgListener();
smackUtil.sendChatMsg("test1","test2","1111111111111111111111111111111111111");
smackUtil.sendPacketMsg("test1","test2","1111111111111111111111111111111111111");
try {
Thread.sleep(1000*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
test2 登陸併發送訊息:
public static void main(String[] args) {
SmackUtil smackUtil = new SmackUtil();
smackUtil.init();
smackUtil.seeConfig();
smackUtil.seeConnection();
smackUtil.login("test2", "test2");
smackUtil.addMsgListener();
smackUtil.sendChatMsg("test2","test1","222222222222222222222222222222222222222");
smackUtil.sendPacketMsg("test2","test1","222222222222222222222222222222222222222");
try {
Thread.sleep(100*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
執行後可以分別在這兩個控制檯上看到收到的訊息
看到這裡,說明已經可以正常通訊,收發訊息了。