目錄
XMPP協議背景:
即時通信( Instant Messaging,簡稱 IM) 像qq.微信
沒有統一的標準,無法實現互聯互通, 用統一的協議XMPP
XMPP 協議是以 XML 爲基礎的 ,XMPP 信息不僅可以是簡單的文本,而且可以攜帶複雜的數據和各種格式的文件,
也就是說 XMPP 協議不僅可以用在人與人之間的交流,而且可以實現軟件與軟件或軟件與人之間的交流
XMPP 中定義了三個角色, 客戶端,服務器,網關
openfire服務端
Openfire 是基於XMPP 協議的IM 的服務器端的一個實現
參考 http://myopenfire.com/article/articledir/1
Openfire是一個Java應用程序,
Openfire採用內置的jetty作web服務器,在啓動AdminConsolePlugin插件時調用startup()方法啓動jetty服務器,9090爲其明文端口,9091爲其加密端口。 啓動成功後, 可以從網站進入http://ip:9090 openfire管理控制檯
設置服務端端口,客戶端連接設置,策略設置,離線消息的存儲
openfire需要用到數據庫:
ofGroup (用戶組的數據)
ofGroupUser (組成員)
ofUser (用戶數據)
ofOffline (離線郵件存儲)
插件開發
下載源碼,生成eclipse項目,添加項目依賴的Jar包,運行openfire
Spark Smack客戶端
Smack 是一個XMPP 協議的Java 實現,提供一套可擴展的API
Spark 提供了客戶端一個基本的實現,並提出了一個很好的插件架構
例: java客戶端發送消息
package com.openfire.client;
import java.io.IOException;
import java.util.Scanner;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatManagerListener;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
/**
* Hello XMPP!
*
*/
public class App extends Thread
{
void say() {
};
public static void main( String[] args ) throws SmackException, IOException, XMPPException, InterruptedException
{
// 對連接的配置
XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
builder.setUsernameAndPassword("admin", "123456");
builder.setServiceName("ww110"); //openfire服務端名字,登錄管理後臺可查看
builder.setHost("192.168.0.110");
builder.setPort(5222);
// 不加這行會報錯,因爲沒有證書
builder.setSecurityMode(SecurityMode.disabled);
//SASLAuthentication.supportSASLMechanism("PLAIN",0);
builder.setDebuggerEnabled(true);
XMPPTCPConnectionConfiguration config = builder.build();
// 建立連接並登陸
AbstractXMPPConnection c = new XMPPTCPConnection(config);
c.addPacketSendingListener(new StanzaListener() {
@Override
public void processPacket(Stanza st) throws NotConnectedException {
System.out.println("in StanzaListener:" + st.getFrom());
}
}, new StanzaFilter() {
@Override
public boolean accept(Stanza st) {
System.out.println("in StanzaFilter:" + st.getFrom());
return false;
}
});
c.connect();
c.login();
ChatManager chatManager = ChatManager.getInstanceFor(c);
chatManager.addChatListener(new ChatManagerListener() {
@Override
public void chatCreated(Chat cc, boolean bb) {
// 當收到來自對方的消息時觸發監聽函數
cc.addMessageListener(new ChatMessageListener() {
@Override
public void processMessage(Chat cc, Message mm) {
System.out.println("app2收到消息:" + cc + mm.getBody());
}
});
}
});
while (true) {
sleep(2000);
//每2秒給new1用戶發消息
Chat chat = chatManager.createChat("new1@ww110");
chat.getThreadID(); Message msg = new Message();
msg.setBody("你好,我是機器人");
chat.sendMessage(msg);
}
}
}