欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中基于XMPP協(xié)議實(shí)現(xiàn)IM聊天程序與多人聊天室

 更新時(shí)間:2016年02月24日 15:59:31   作者:喝醉的毛毛蟲  
這篇文章主要介紹了Android中基于XMPP協(xié)議實(shí)現(xiàn)IM聊天程序與多人聊天室的方法,XMPP基于XML數(shù)據(jù)格式傳輸,一般用于即時(shí)消息(IM)以及在線現(xiàn)場探測,需要的朋友可以參考下

簡單的IM聊天程序
由于項(xiàng)目需要做一個(gè)基于XMPP協(xié)議的Android通訊軟件。故開始研究XMPP。
XMPP協(xié)議采用的是客戶端-服務(wù)器架構(gòu),所有從一個(gè)客戶端發(fā)到另一個(gè)客戶端的消息和數(shù)據(jù)都必須經(jīng)過XMPP服務(wù)器轉(zhuǎn)發(fā),而且支持服務(wù)器間DNS的路由,也就是說可以構(gòu)建服務(wù)器集群,使不同的

服務(wù)器下的客戶端也可以通信,XMPP的前身是一個(gè)開源組織制定的網(wǎng)絡(luò)通信協(xié)議——Jabber,XMPP的核心是在網(wǎng)絡(luò)上分片段發(fā)送XML流的協(xié)議,這個(gè)協(xié)議是XMPP的即時(shí)通訊指令的傳遞手段。
      為了防止服務(wù)器間發(fā)送的數(shù)據(jù)被篡改或偷聽,XMPP服務(wù)器通信引入了TLS機(jī)制,使用TLS機(jī)制能實(shí)現(xiàn)數(shù)據(jù)的加密,從而保證了在數(shù)據(jù)傳輸過程種數(shù)據(jù)的安全。
      一個(gè)XMPP實(shí)體的地址稱為Jabber Identifier或JID,作用類似于IP地址。一個(gè)合法的JID包括節(jié)點(diǎn)名,域名資源名,其格式為:jid=[node'@']domain['/'resource]

XMPP協(xié)議的命名空間:

  • jabber:iq:private   -- 私有數(shù)據(jù)存儲,用于本地用戶私人設(shè)置信息,比如用戶備注等。
  • jabber:iq:conference  -- 一般會(huì)議,用于多個(gè)用戶之間的信息共享
  • jabber:x:encrypted -- 加密的消息,用于發(fā)送加密消息
  • jabber:x:expire  -- 消息終止
  • jabber:iq:time  -- 客戶端時(shí)間
  • jabber:iq:auth  -- 簡單用戶認(rèn)證,一般用于服務(wù)器之間或者服務(wù)器和客戶端之間的認(rèn)證
  • jabber:x:roster  -- 內(nèi)部花名冊
  • jabber:x:signed  -- 標(biāo)記的在線狀態(tài)
  • jabber:iq:search -- 用戶數(shù)據(jù)庫查詢,用于向服務(wù)器發(fā)送查詢請求
  • jabber:iq:register -- 注冊請求,用于用戶注冊相關(guān)信息
  • jabber:x:iq:roster -- 花名冊管理
  • jabber:x:conference -- 會(huì)議邀請,用于向參加會(huì)議用戶發(fā)送開會(huì)通知
  • jabber:x:event  -- 消息事件
  • vcard-temp  -- 臨時(shí)的vCard,用于設(shè)置用戶的頭像以及昵稱等

 在網(wǎng)上找了下,有開源的項(xiàng)目BEEM,開源的用于android的xmpp框架asmack,asmack是smack的android版本?,F(xiàn)在開始學(xué)習(xí)smack

。Xmpp就是神馬東西,就不廢話了。首先在網(wǎng)上下一個(gè)Openfire和Spack,不知道這兩個(gè)是什么東西,就直接google吧。安裝openfire需要mysql的支持,當(dāng)然,oracle,sqlserver肯定是可以的。還是先上圖吧:

Openfire + Spark + MyXMPPP

2016224155319690.gif (1024×394)

2016224155354184.gif (518×647)

import java.io.InputStreamReader; 
import java.util.Collection; 
 
import org.jivesoftware.smack.Chat; 
import org.jivesoftware.smack.ChatManager; 
import org.jivesoftware.smack.ChatManagerListener; 
import org.jivesoftware.smack.ConnectionConfiguration; 
import org.jivesoftware.smack.MessageListener; 
import org.jivesoftware.smack.PrivacyListManager; 
import org.jivesoftware.smack.Roster; 
import org.jivesoftware.smack.RosterEntry; 
import org.jivesoftware.smack.RosterGroup; 
import org.jivesoftware.smack.RosterListener; 
import org.jivesoftware.smack.XMPPConnection; 
import org.jivesoftware.smack.packet.Message; 
import org.jivesoftware.smack.packet.Presence; 
 
public class TestSmack { 
  public static void main(String[] args) {XMPPConnection.DEBUG_ENABLED = true; 
    //我的電腦IP:10.16.25.90 
    final ConnectionConfiguration connectionConfig = new ConnectionConfiguration("10.16.25.91", 5222, ""); 
    connectionConfig.setSASLAuthenticationEnabled(false); 
        try { 
           
          XMPPConnection connection = new XMPPConnection(connectionConfig); 
          connection.connect();//連接 
          connection.login("test", "test");//登陸 
          System.out.println(connection.getUser()); 
          ChatManager chatmanager = connection.getChatManager(); 
 
          //新建一個(gè)會(huì)話 
          Chat newChat = chatmanager.createChat("test3@pc2010102716", new MessageListener() { 
            public void processMessage(Chat chat, Message message) { 
              System.out.println("Received from 【" + message.getFrom() + "】 message: " + message.getBody()); 
            } 
          }); 
           
          // 監(jiān)聽被動(dòng)接收消息,或廣播消息監(jiān)聽器 
          chatmanager.addChatListener(new ChatManagerListener() { 
            @Override 
            public void chatCreated(Chat chat, boolean createdLocally) { 
              chat.addMessageListener(new MessageListener() { 
                @Override 
                public void processMessage(Chat chat, Message message) { 
                  System.out.println("Received from 【" + message.getFrom() + "】 message: " + message.getBody()); 
                } 
                   
              }); 
            } 
          }); 
          //發(fā)送消息 
          newChat.sendMessage("我是菜鳥"); 
           
          //獲取花名冊 
          Roster roster = connection.getRoster(); 
          Collection<RosterEntry> entries = roster.getEntries(); 
          for(RosterEntry entry : entries) { 
            System.out.print(entry.getName() + " - " + entry.getUser() + " - " + entry.getType() + " - " + entry.getGroups().size()); 
            Presence presence = roster.getPresence(entry.getUser()); 
            System.out.println(" - " + presence.getStatus() +" - "+ presence.getFrom()); 
          } 
           
          //添加花名冊監(jiān)聽器,監(jiān)聽好友狀態(tài)的改變。 
          roster.addRosterListener(new RosterListener() { 
 
            @Override 
            public void entriesAdded(Collection<String> addresses) { 
              System.out.println("entriesAdded"); 
            } 
 
            @Override 
            public void entriesUpdated(Collection<String> addresses) { 
              System.out.println("entriesUpdated"); 
            } 
 
            @Override 
            public void entriesDeleted(Collection<String> addresses) { 
              System.out.println("entriesDeleted"); 
            } 
 
            @Override 
            public void presenceChanged(Presence presence) { 
              System.out.println("presenceChanged - >" + presence.getStatus()); 
            } 
             
          }); 
           
          //創(chuàng)建組 
//         /RosterGroup group = roster.createGroup("大學(xué)"); 
//         for(RosterEntry entry : entries) { 
//           group.addEntry(entry); 
//         } 
          for(RosterGroup g : roster.getGroups()) { 
            for(RosterEntry entry : g.getEntries()) { 
              System.out.println("Group " +g.getName() +" >> " + entry.getName() + " - " + entry.getUser() + " - " + entry.getType() + " - " + entry.getGroups().size()); 
            } 
          } 
           
          //發(fā)送消息 
          BufferedReader cmdIn = new BufferedReader(new InputStreamReader(System.in)); 
          while(true) { 
           try { 
             String cmd = cmdIn.readLine(); 
             if("!q".equalsIgnoreCase(cmd)) { 
               break; 
             } 
             newChat.sendMessage(cmd); 
           }catch(Exception ex) { 
           } 
          } 
          connection.disconnect(); 
          System.exit(0); 
        } catch (Exception e) { 
          e.printStackTrace(); 
        } 
  } 
} 

以上代碼如果在一般的Java Project上運(yùn)行需要加入smack.jar 和klmx2.jar,如果是Android Project,基本代碼不需改變只需將其放入onCreate(...)方法下即可,需要加入asmack.jar包.

1、ConnectionConfiguration
 作為用于與XMPP服務(wù)建立連接的配置。它能配置;連接是否使用TLS,SASL加密。
 包含內(nèi)嵌類:ConnectionConfiguration.SecurityMode

2、XMPPConnection.
 XMPPConnection這個(gè)類用來連接XMPP服務(wù).
 可以使用connect()方法建立與服務(wù)器的連接。disconnect()方法斷開與服務(wù)器的連接.
 在創(chuàng)建連接前可以使用XMPPConnection.DEBUG_ENABLED = true; 使開發(fā)過程中可以彈出一個(gè)GUI窗口,用于顯示我們的連接與發(fā)送Packet的信息。

2016224155444002.gif (713×349)

3、ChatManager
 用于監(jiān)控當(dāng)前所有chat??梢允褂胏reateChat(String userJID, MessageListener listener)創(chuàng)建一個(gè)聊天。
 
4、Chat
 Chat用于監(jiān)控兩個(gè)用戶間的一系列message。使用addMessageListener(MessageListener listener)當(dāng)有任何消息到達(dá)時(shí)將會(huì)觸發(fā)listener的processMessage(Chat chat, Message message)
方法.
 我們可以使用sendMessage()發(fā)送消息,這個(gè)方法有兩個(gè)重載方法,一種類類型的參數(shù)時(shí)String類型,另一種則是傳入Message對象(后面介紹)。
 那么有這樣一種情況,當(dāng)別人主動(dòng)跟我們建立連接發(fā)送消息,或者系統(tǒng)發(fā)送消息時(shí)我們怎么才能接收消息呢?
    我現(xiàn)在是這樣操作的:

 chatmanager.addChatListener(new ChatManagerListener() {
 @Override
 public void chatCreated(Chat chat, boolean createdLocally) {
  chat.addMessageListener(new MessageListener() {
  @Override
  public void processMessage(Chat chat, Message message) {
   System.out.println("Received message: " + message.getBody());
  }
     
  });
 }
 });

 
5、Message

  •  Message用于表示一個(gè)消息包(可以用調(diào)試工具看到發(fā)送包和接收包的具體內(nèi)容)。它有以下多種類型。
  •   Message.Type.NORMAL -- (默認(rèn))文本消息(比如郵件)
  •   Message.Type.CHAT -- 典型的短消息,如QQ聊天的一行一行顯示的消息
  •   Message.Type.GROUP_CHAT -- 群聊消息
  •   Message.Type.HEADLINE -- 滾動(dòng)顯示的消息
  •   Message.TYPE.ERROR -- 錯(cuò)誤的消息
  •  Message有兩個(gè)內(nèi)部類:
  •   Message.Body -- 表示消息體
  •   Message.Type -- 表示消息類型

6、Roster
 表示存儲了很多RosterEntry的一個(gè)花名冊.為了易于管理,花名冊的項(xiàng)被分貝到了各個(gè)group中.
 當(dāng)建立與XMPP服務(wù)的連接后可以使用connection.getRoster()獲取Roster對象。
 別的用戶可以使用一個(gè)訂閱請求(相當(dāng)于QQ加好友)嘗試訂閱目的用戶??梢允褂妹杜e類型Roster.SubscriptionMode的值處理這些請求:
 accept_all: 接收所有訂閱請求
 reject_all:拒絕所有訂閱請求
 manual:  手工處理訂閱請求
 
 創(chuàng)建組:RosterGroup group = roster.createGroup("大學(xué)");
 向組中添加RosterEntry對象: group.addEntry(entry);
 
7、RosterEntry
 表示Roster(花名冊)中的每條記錄.它包含了用戶的JID,用戶名,或用戶分配的昵稱.
 
8、RosterGroup
 表示RosterEntry的組??梢允褂胊ddEntry(RosterEntry entry)添加。contains(String user) 判斷某用戶是否在組中.當(dāng)然removeEntry(RosterEntry entry)就是從組中移除了。getEntries()

獲取所有RosterEntry.
 
9、Presence
 表示XMPP狀態(tài)的packet。每個(gè)presence packet都有一個(gè)狀態(tài)。用枚舉類型Presence.Type的值表示:
 available -- (默認(rèn))用戶空閑狀態(tài)
 unavailable -- 用戶沒空看消息
 subscribe -- 請求訂閱別人,即請求加對方為好友
 subscribed -- 統(tǒng)一被別人訂閱,也就是確認(rèn)被對方加為好友
 unsubscribe -- 他取消訂閱別人,請求刪除某好友
 unsubscribed -- 拒絕被別人訂閱,即拒絕對放的添加請求
 error -- 當(dāng)前狀態(tài)packet有錯(cuò)誤
 內(nèi)嵌兩個(gè)枚舉類型:Presence.Mode和Presence.Type.
 可以使用setStatus自定義用戶當(dāng)前的狀態(tài)(像QQ一樣的)


MultiUserChat聊天室

import java.io.BufferedReader;  
import java.io.InputStreamReader;  
import java.util.ArrayList;  
import java.util.Collection;  
import java.util.Iterator;  
import java.util.List;  
 
import org.jivesoftware.smack.Chat;  
import org.jivesoftware.smack.ConnectionConfiguration;  
import org.jivesoftware.smack.MessageListener;  
import org.jivesoftware.smack.PacketListener;  
import org.jivesoftware.smack.SmackConfiguration;  
import org.jivesoftware.smack.XMPPConnection;  
import org.jivesoftware.smack.XMPPException;  
import org.jivesoftware.smack.packet.Message;  
import org.jivesoftware.smack.packet.Packet;  
import org.jivesoftware.smack.provider.ProviderManager;  
import org.jivesoftware.smackx.Form;  
import org.jivesoftware.smackx.FormField;  
import org.jivesoftware.smackx.ServiceDiscoveryManager;  
import org.jivesoftware.smackx.muc.DefaultParticipantStatusListener;  
import org.jivesoftware.smackx.muc.DefaultUserStatusListener;  
import org.jivesoftware.smackx.muc.DiscussionHistory;  
import org.jivesoftware.smackx.muc.HostedRoom;  
import org.jivesoftware.smackx.muc.InvitationListener;  
import org.jivesoftware.smackx.muc.InvitationRejectionListener;  
import org.jivesoftware.smackx.muc.MultiUserChat;  
import org.jivesoftware.smackx.muc.RoomInfo;  
import org.jivesoftware.smackx.muc.SubjectUpdatedListener;  
import org.jivesoftware.smackx.packet.ChatStateExtension;  
import org.jivesoftware.smackx.packet.DiscoverInfo;  
import org.jivesoftware.smackx.packet.DiscoverItems;  
import org.jivesoftware.smackx.packet.OfflineMessageInfo;  
import org.jivesoftware.smackx.packet.OfflineMessageRequest;  
import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;  
import org.jivesoftware.smackx.provider.BytestreamsProvider;  
import org.jivesoftware.smackx.provider.DataFormProvider;  
import org.jivesoftware.smackx.provider.DiscoverInfoProvider;  
import org.jivesoftware.smackx.provider.DiscoverItemsProvider;  
import org.jivesoftware.smackx.provider.IBBProviders;  
import org.jivesoftware.smackx.provider.MUCAdminProvider;  
import org.jivesoftware.smackx.provider.MUCOwnerProvider;  
import org.jivesoftware.smackx.provider.MUCUserProvider;  
import org.jivesoftware.smackx.provider.StreamInitiationProvider;  
import org.jivesoftware.smackx.provider.VCardProvider;  
import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;  
 
public class TestSmack2 {  
  public static void main(String[] args) {XMPPConnection.DEBUG_ENABLED = true;  
    final ConnectionConfiguration connectionConfig = new ConnectionConfiguration("PC2010102716", 5222, ""); 
    connectionConfig.setSASLAuthenticationEnabled(false);  
    ProviderManager pm = ProviderManager.getInstance();  
    configure(pm);  
    try {  
      XMPPConnection connection = new XMPPConnection(connectionConfig);  
      connection.connect();//連接  
      initFeatures(connection);  
      connection.login("test", "test");//登陸  
      //聊天室  
      //MultiUserChat multiUserChat = new MultiUserChat(connection, new InvitationListener() {}); 
       //查找服務(wù)  
      System.out.println(connection.getServiceName());  
      List<String> col = getConferenceServices(connection.getServiceName(), connection); 
      for (Object aCol : col) {  
        String service = (String) aCol;  
         //查詢服務(wù)器上的聊天室  
        Collection<HostedRoom> rooms = MultiUserChat.getHostedRooms(connection, service); 
        for(HostedRoom room : rooms) {  
          //查看Room消息  
          System.out.println(room.getName() + " - " +room.getJid());  
          RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, room.getJid()); 
          if(roomInfo != null) {  
            System.out.println(roomInfo.getOccupantsCount() + " : " + roomInfo.getSubject()); 
          }   
         }   
      }  
     
      /*---創(chuàng)建默認(rèn)配置的聊天室 --- 
      先看看官方的文檔: 
      Creates a new multi user chat with the specified connection and room name. Note: no 
         * information is sent to or received from the server until you attempt to 
         * {@link #join(String) join} the chat room. On some server implementations, 
         * the room will not be created until the first person joins it 
         * 最重要一句:直到用戶調(diào)用join方法的時(shí)候聊天室才會(huì)被創(chuàng)建 
         */  
      MultiUserChat muc = new MultiUserChat(connection, "instant@conference.pc2010102716"); 
       muc.create("user1");  
      muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));  
     
      //----創(chuàng)建手動(dòng)配置聊天室----  
      muc = new MultiUserChat(connection, "reserved4@conference.pc2010102716");  
     
      //銷毀聊天室  
      //muc.destroy("Test", null);  
      muc.create("user2");  
      //獲取聊天室的配置表單  
      Form form = muc.getConfigurationForm();  
      //根據(jù)原始表單創(chuàng)建一個(gè)要提交的新表單  
      Form submitForm = form.createAnswerForm();  
      //向提交的表單添加默認(rèn)答復(fù)  
      for(Iterator<FormField> fields = form.getFields(); fields.hasNext();) {  
        FormField field = (FormField) fields.next();  
        if(!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) { 
          submitForm.setDefaultAnswer(field.getVariable());  
        }  
      }  
      //重新設(shè)置聊天室名稱  
      submitForm.setAnswer("muc#roomconfig_roomname", "Reserved4 Room");  
      //設(shè)置聊天室的新?lián)碛姓? 
      List<String> owners = new ArrayList<String>();  
      owners.add("test@pc2010102716");  
      submitForm.setAnswer("muc#roomconfig_roomowners", owners);  
      //設(shè)置密碼  
      submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);  
      submitForm.setAnswer("muc#roomconfig_roomsecret", "reserved");  
      //設(shè)置描述  
      submitForm.setAnswer("muc#roomconfig_roomdesc", "新創(chuàng)建的reserved聊天室");  
      //設(shè)置聊天室是持久聊天室,即將要被保存下來  
      //submitForm.setAnswer("muc#roomconfig_persistentroom", true);  
      //發(fā)送已完成的表單到服務(wù)器配置聊天室  
      muc.sendConfigurationForm(submitForm);  
     
      //加入聊天室(使用昵稱喝醉的毛毛蟲 ,使用密碼ddd)  
      muc = new MultiUserChat(connection, "ddd@conference.pc2010102716");  
      muc.join("喝醉的毛毛蟲", "ddd");  
     
      //監(jiān)聽消息  
      muc.addMessageListener(new PacketListener() {  
        @Override  
        public void processPacket(Packet packet) {  
          Message message = (Message) packet;  
          System.out.println(message.getFrom() + " : " + message.getBody());;  
        }  
      });  
     
      //muc = new MultiUserChat(connection, "ddd@conference.pc2010102716");  
      //muc.join("喝醉的毛毛蟲", "ddd");  
     
      //加入聊天室(使用昵稱喝醉的毛毛蟲 ,使用密碼ddd)并且獲取聊天室里最后5條信息,  
      //注:addMessageListener監(jiān)聽器必須在此join方法之前,否則無法監(jiān)聽到需要的5條消息  
      muc = new MultiUserChat(connection, "ddd@conference.pc2010102716");  
      DiscussionHistory history = new DiscussionHistory();  
      history.setMaxStanzas(5);  
      muc.join("喝醉的毛毛蟲", "ddd", history, SmackConfiguration.getPacketReplyTimeout());  
     
      //監(jiān)聽拒絕加入聊天室的用戶  
      muc.addInvitationRejectionListener(new InvitationRejectionListener() {  
        @Override  
        public void invitationDeclined(String invitee, String reason) {  
        System.out.println(invitee + " reject invitation, reason is " + reason);  
        }  
      });  
      //邀請用戶加入聊天室  
      muc.invite("test3@pc2010102716", "大家來談?wù)勅松?);  
      //監(jiān)聽邀請加入聊天室請求  
      MultiUserChat.addInvitationListener(connection, new InvitationListener() {  
        @Override  
        public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password, Message message) {  
        //例:直接拒絕邀請  
        MultiUserChat.decline(conn, room, inviter, "你丫很閑啊!");  
        }  
      });  
     
     
      //根據(jù)roomJID獲取聊天室信息  
      RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, "ddd@conference.pc2010102716"); 
       System.out.println(roomInfo.getRoom() + "-" + roomInfo.getSubject() + "-" + roomInfo.getOccupantsCount()); 
        
      //判斷用戶是否支持Multi-User聊天協(xié)議  
      //注:需要加上資源標(biāo)識符  
      boolean supports = MultiUserChat.isServiceEnabled(connection, "test3@pc2010102716/spark"); 
       //獲取某用戶所加入的聊天室  
      if(supports) {  
        Iterator<String> joinedRooms = MultiUserChat.getJoinedRooms(connection, "test3@pc2010102716/spark"); 
        while(joinedRooms.hasNext()) {  
          System.out.println("test3 has joined Room " + joinedRooms.next());  
        }  
      }  
     
      //與聊天室用戶私聊  
      Chat chat = muc.createPrivateChat("ddd@conference.pc2010102716/飛鳥", new MessageListener() { 
         @Override  
         public void processMessage(Chat chat, Message message) {  
           System.out.println("Private Chat: Received message from " + message.getFrom() + "-" + message.getBody()); 
         }  
      });  
      chat.sendMessage("今天不用加班吧?");  
     
      //改變聊天室主題  
      muc.addSubjectUpdatedListener(new SubjectUpdatedListener() {  
        @Override  
        public void subjectUpdated(String subject, String from) {  
          System.out.println("Subject updated to " + subject +" by " + from);  
        }  
      });  
      //muc.changeSubject("New Subject11");  
     
      /*一個(gè)成員可能有四種角色: 
      1:主持者(Moderator) (權(quán)限最大的角色,管理其他成員在聊天室中的角色 
      2:參與者(Participant 
      3:游客 (Visitor) (不能向所有成員發(fā)送消息) 
      4:無(沒有角色)(NONE) 
      */  
     
      /*聊天室用戶可以有5種從屬關(guān)系 
       * 1、所有者 Owner 
       * 2、管理員 Admin 
       * 3、成員 Member 
       * 4、被驅(qū)逐者 Outcast 
       * 5、無(不存在從屬關(guān)系) None 
       */  
     
      //配置聊天室為Moderated聊天室  
      form = muc.getConfigurationForm();  
      Form answerForm = form.createAnswerForm();  
      answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");  
      muc.sendConfigurationForm(answerForm);  
     
      //監(jiān)聽自己的狀態(tài)變更和事件  
      muc.addUserStatusListener(new DefaultUserStatusListener() {  
        @Override  
        public void voiceRevoked() {  
          super.voiceRevoked();  
          System.out.println("你被禁言了!");  
        }  
       
        @Override  
        public void voiceGranted() {  
          super.voiceGranted();  
          System.out.println("你被批準(zhǔn)發(fā)言了!");  
        }  
       
        @Override  
        public void membershipGranted() {  
          super.membershipGranted();  
          System.out.println("你被賦予了Member權(quán)限");  
        }  
       
        @Override  
        public void membershipRevoked() {  
          super.membershipRevoked();  
          System.out.println("你被解除了Member權(quán)限");  
        }  
       
        @Override  
        public void adminGranted() {  
          super.adminGranted();  
          System.out.println("你被賦予了管理員權(quán)限");  
        }  
       
        @Override  
        public void adminRevoked() {  
        super.adminRevoked();  
        System.out.println("你被解除了管理員權(quán)限");  
        }  
      //......  
      });  
      //房主(Owner)批準(zhǔn)test3發(fā)言權(quán)  
      muc.grantVoice("test3@pc2010102716");  
     
      //監(jiān)聽他人狀態(tài)變更  
      muc.addParticipantStatusListener(new DefaultParticipantStatusListener() {  
     
        @Override  
        public void voiceGranted(String participant) {  
          super.voiceGranted(participant);  
        System.out.println(participant + "被批準(zhǔn)發(fā)言了!");  
        }  
       
        @Override  
        public void voiceRevoked(String participant) {  
          super.voiceRevoked(participant);  
          System.out.println(participant + "被禁言了!");  
        }  
       
        @Override  
        public void membershipRevoked(String participant) {  
          super.membershipRevoked(participant);  
        }  
       
        @Override  
        public void adminGranted(String participant) {  
          super.adminGranted(participant);  
        }  
       
        @Override  
        public void adminRevoked(String participant) {  
          super.adminRevoked(participant);  
        }  
     
      });  
     
      //房主(Owner)批準(zhǔn)test3管理員特權(quán)  
      muc.grantAdmin("test3@pc2010102716");  
   
   
      //發(fā)送消息  
      BufferedReader cmdIn = new BufferedReader(new InputStreamReader(System.in));  
      while(true) {  
        try {  
           String cmd = cmdIn.readLine();  
           if("!q".equalsIgnoreCase(cmd)) {  
             break;  
           }  
         }catch(Exception ex) {  
         }  
      }  
      connection.disconnect();  
      System.exit(0);     
    } catch (Exception e) {  
      e.printStackTrace();  
    }  
  }  
 
  public static List<String> getConferenceServices(String server, XMPPConnection connection) throws Exception { 
   List<String> answer = new ArrayList<String>();  
      ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); 
       DiscoverItems items = discoManager.discoverItems(server);  
      for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext();) { 
         DiscoverItems.Item item = (DiscoverItems.Item)it.next();  
        if (item.getEntityID().startsWith("conference") || item.getEntityID().startsWith("private")) { 
           answer.add(item.getEntityID());  
        }  
        else {  
          try {  
            DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); 
             if (info.containsFeature("http://jabber.org/protocol/muc")) { 
               answer.add(item.getEntityID());  
            }  
          }  
          catch (XMPPException e) {  
          }  
        }  
      }  
      return answer;  
    }  
 
 
  private static void configure(ProviderManager pm) {  
    // Service Discovery # Items  
    pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); 
     // Service Discovery # Info  
    pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); 
      
    // Service Discovery # Items  
    pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); 
     // Service Discovery # Info  
    pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); 
      
    //Offline Message Requests  
    pm.addIQProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider()); 
        //Offline Message Indicator  
        pm.addExtensionProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());     
          
    //vCard  
    pm.addIQProvider("vCard","vcard-temp", new VCardProvider());  
 
    //FileTransfer  
    pm.addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider()); 
        pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider()); 
        pm.addIQProvider("open","http://jabber.org/protocol/ibb", new IBBProviders.Open()); 
        pm.addIQProvider("close","http://jabber.org/protocol/ibb", new IBBProviders.Close()); 
        pm.addExtensionProvider("data","http://jabber.org/protocol/ibb", new IBBProviders.Data());     
        //Data Forms  
      pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());  
      //Html  
      pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider()); 
      //Ad-Hoc Command  
      pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());     
    // Chat State  
    ChatStateExtension.Provider chatState = new ChatStateExtension.Provider();  
    pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", chatState); 
    pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates",  
      chatState);  
    pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", chatState); 
    pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", chatState); 
    pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", chatState); 
    //MUC User,Admin,Owner  
    pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider()); 
    pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider()); 
    pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider()); 
  }  
 
  private static void initFeatures(XMPPConnection xmppConnection) {  
    ServiceDiscoveryManager.setIdentityName("Android_IM");  
    ServiceDiscoveryManager.setIdentityType("phone");  
    ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(xmppConnection); 
     if(sdm == null) {  
    sdm = new ServiceDiscoveryManager(xmppConnection);  
    }  
    sdm.addFeature("http://jabber.org/protocol/disco#info");  
    sdm.addFeature("http://jabber.org/protocol/caps");  
    sdm.addFeature("urn:xmpp:avatar:metadata");  
    sdm.addFeature("urn:xmpp:avatar:metadata+notify");  
    sdm.addFeature("urn:xmpp:avatar:data");  
    sdm.addFeature("http://jabber.org/protocol/nick");  
    sdm.addFeature("http://jabber.org/protocol/nick+notify");  
    sdm.addFeature("http://jabber.org/protocol/xhtml-im");  
    sdm.addFeature("http://jabber.org/protocol/muc");  
    sdm.addFeature("http://jabber.org/protocol/commands");  
    sdm.addFeature("http://jabber.org/protocol/si/profile/file-transfer");  
    sdm.addFeature("http://jabber.org/protocol/si");  
    sdm.addFeature("http://jabber.org/protocol/bytestreams");  
    sdm.addFeature("http://jabber.org/protocol/ibb");  
    sdm.addFeature("http://jabber.org/protocol/feature-neg");  
    sdm.addFeature("jabber:iq:privacy");  
  }  
 
}  

上面有兩張Spark客戶端的聊天室列表占有者一列不同的原因:當(dāng)使用以下代碼獲取時(shí)不能獲取occupantsCount和subject的值:  

System.out.println(roomInfo.getOccupantsCount() + " : " + roomInfo.getSubject()); 

這是由于Openfire端有個(gè)bug(暫且這樣說吧,我不知為什么Openfire這樣做).首先修改Smack的一個(gè)bug,修改RoomInfo類的RoomInfo(DiscoverInfo info) 方法:         

Iterator<String> values = form.getField("muc#roominfo_subject").getValues(); 
if (values.hasNext()) { 
  this.subject = values.next(); 
} 
else { 
  this.subject = ""; 
} 
 

改為:   

final FormField subjField = form.getField("muc#roominfo_subject");  
this.subject = subjField == null ? "" : subjField.getValues().next(); 

  修改Openfire的源碼,org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl類的public DataForm getExtendedInfo(String name, String node, JID senderJID) 方法:         

      /*final FormField fieldOcc = dataForm.addField(); */ 
      fieldSubj.setVariable("muc#roominfo_occupants"); 
      fieldSubj.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.occupants")); 
      fieldSubj.addValue(Integer.toString(room.getOccupantsCount())); 

  
改為:         

final FormField fieldOccu= dataForm.addField(); 
fieldOccu.setVariable("muc#roominfo_occupants"); 
fieldOccu.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.occupants")); 
fieldOccu.addValue(Integer.toString(room.getOccupantsCount()));  

2016224155734617.gif (496×393)

2016224155755589.gif (497×397)

2016224155813935.gif (495×397)

2016224155833876.gif (499×403)

2016224155851017.gif (1024×419)

2016224155906465.gif (1024×510)

使用asmack開發(fā)基于Android的IM系統(tǒng)同理.

相關(guān)文章

最新評論