XMPP大雜燴
XMPP大雜燴
對XMPP的理解
XMPP是基於XML的即時通訊協議。對即時通訊場景進行了高度抽象,比如用訂閱對方的上下線狀態表示好友。提供了文字通訊、使用者上下線通知、聯絡人管理、群組聊天等功能,還可以安裝外掛或自行拓展。
服務端的安裝
服務端一般用OpenFire。
以macOS為例,官網直接下載安裝包,安裝完成後,在系統選單中開啟OpenFire控制檯,進入OpenFire的Web後臺,走完配置嚮導。資料庫可以用OpenFire自帶的嵌入式資料庫,也可以配置為SQL/">MySQL。如果是區域網測試的話,主機名最好設定成內網IP。最後一步需要設定管理員密碼,管理員的賬號是admin。配置完成後,可以登入OpenFire的管理後臺。
OpenFire伺服器預設開放使用者註冊、開放建群,所以可以不管OpenFire後臺,直接拿來使用。
使用者註冊
大多XMPP客戶端不提供使用者註冊功能,所以最好在OpenFire後臺直接新增使用者。試了多個客戶端,只有Psi可以成功註冊使用者,而且登入之後找不到退出的地方,也找不到建立使用者的地方。
客戶端的選擇
XMPP的圖形客戶端特別多,但是一個比一個難用。在macOS上勉強可以使用的主要有Spark、Adium和Thunderbird。Spark是OpenFire官方提供的客戶端,在使用時要注意禁用安全選項,如果主機不受信任的話。
命令列下的客戶端,可以使用Profanity
使用者登入
登入XMPP賬戶,需要伺服器、使用者名稱、密碼三個欄位。如果客戶端沒有提供單獨的伺服器輸入框的話,使用者名稱改用使用者名稱@伺服器
Profanity的使用
Profanity不提供使用者註冊功能,需要先在後臺新增使用者,或者用其他客戶端註冊。
-
登入
/connect 使用者名稱@伺服器 tls disable
-
登出
/disconnect
-
開啟聊天
/msg 使用者名稱@伺服器/使用者暱稱 文字
-
切換視窗
Alt/Option+數字
Alt+1是系統視窗,其他是聊天視窗 -
新增使用者到通訊錄(非好友,不能訂閱使用者的上下線訊息)
/roster add 使用者名稱@伺服器
-
新增使用者為好友
/sub request 使用者名稱@伺服器
-
收到新增好友請求時允許
/sub allow 使用者名稱@伺服器
-
進入聊天室/群組/房間,不存在則根據嚮導建立
/join 房間名@伺服器
-
切換線上狀態
/away
=離開/online
=線上/dnd
=忙碌 ... -
退出軟體
/quit
Smack的使用
Smack是OpenFire提供的支援XMPP協議的Java介面
引入Smack依賴
- org.igniterealtime.smack:smack-tcp 同時包含了Smack核心庫。之所以有這個包,是因為XMPP也能執行在其他協議之上
- org.igniterealtime.smack:smack-java7 平臺依賴。用作初始化。不包含此庫也能編譯成功,但是跑不起來
- org.igniterealtime.smack:smack-extensions Smake擴充套件包。算是必備,至少聯絡人管理功能需要這個包
Smack示例程式碼
package bj; import io.vavr.control.Try; import lombok.extern.slf4j.Slf4j; import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.chat2.ChatManager; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.RosterEntry; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.junit.Test; import org.jxmpp.jid.impl.JidCreate; import java.io.IOException; import java.net.InetAddress; import java.util.Set; /** * Created by [email protected] at 2018/11/22 下午4:33 */ @Slf4j public class BazTest { @Test public void testAlpha() throws IOException, InterruptedException, XMPPException, SmackException { // 建立連線,並連線到伺服器 AbstractXMPPConnection connection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword("gamma", "gamma") .setXmppDomain("172.16.5.254") .setHostAddress(InetAddress.getByName("172.16.5.254")) // 伺服器地址直接用IP的話,不能用setHost() .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled) // 禁用安全模式,如果伺服器不受信任 .build()).connect(); connection.login(); // 監聽XMPP包(包括PING、線上狀態、聊天訊息等) connection.addSyncStanzaListener(packet -> log.info("[SyncStanzaListener] Packet received {}", packet), stanza -> true); // 只監聽聊天訊息 ChatManager.getInstanceFor(connection).addIncomingListener((entityBareJid, message, chat) -> { System.out.println(String.format("[IncomingListener] Message received %s : %s", entityBareJid, message.getBody())); // Echo此訊息 Try.run(() -> chat.send(message.getBody())); System.out.println(Roster.getInstanceFor(connection).getEntries()); }); // 傳送訊息 connection.sendStanza(new Message("[email protected]", "MESSAGE_BY_CONNECTION")); // 傳送訊息 方式二 ChatManager.getInstanceFor(connection).chatWith(JidCreate.entityBareFrom("[email protected]")).send("MESSAGE_BY_CHAT_MANAGER"); // 獲取聯絡人集合 Thread.sleep(1000); // 等待聯絡人更新 Set<RosterEntry> entries = Roster.getInstanceFor(connection).getEntries(); log.info("Contacts: {} persons", entries.size()); entries.forEach(System.out::println); // 保持執行 Thread.currentThread().join(); } }
控制檯日誌
10:55:24.924 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received IQ Stanza (query jabber:iq:roster) [[email protected]/612m1g1ciz,id=gvsBl-5,type=result,] 10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/1gwvh0rdvv,id=L85kQ-6,type=available,] 10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/1pj92olp11,id=RamcN-7,type=available,] 10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/8aadbwm30s,id=xkaYN-7,type=available,] 10:55:24.934 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/profanity,id=prof_presence_595,type=available,] 10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/9trigmn7f2,id=SJ41s-7,type=available,] 10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/42awvmq6te,id=iMJUx-6,type=available,] 10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/92ijqtzgxi,id=9gG6o-7,type=available,] 10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/494vwn454w,id=byYRm-7,type=available,] 10:55:24.938 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/4wurqkoj8y,id=3BnGN-7,type=available,] 10:55:24.939 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [[email protected]/612m1g1ciz,[email protected]/9vx8ve5vdm,id=YSZxk-6,type=available,] 10:55:25.939 [main] INFO bj.BazTest - Contacts: 3 persons : [email protected] : [email protected] : [email protected] 10:55:26.876 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Message Stanza [[email protected]/612m1g1ciz,[email protected]/profanity,id=prof_msg_670,type=chat,] [IncomingListener] Message received [email protected] : hello [: [email protected], : [email protected], : [email protected]] 10:55:28.839 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Message Stanza [[email protected]/612m1g1ciz,[email protected]/profanity,id=prof_msg_671,type=chat,] [IncomingListener] Message received [email protected] : world [: [email protected], : [email protected], : [email protected]]
文章首發ofollow,noindex" target="_blank">https://baijifeilong.github.io/2018/11/22/xmpp