使用Smack碰到若干問題的解決

 

前一段時間在我自己的視頻會議系統中用到了smack,我想有必要小結一下。其實關於smack的介紹和使用方法,網上還是挺多的,尤其是官網上面,有很詳細的文檔可以查考。所以具體的使用方法,我覺得我沒有必要寫在這裏。我需要在這裏總結的是我碰到的一些問題,同時目前網上對於這些問題的處理方法還不太詳細。

首先是發送消息和接收消息的監聽,這裏得分兩種情況,一種是自己先主動發消息給別人,需要通過

chat = chatManager.createChat(buddyJID, messageListener);
chat.sendMessage(message);

 這個方法中chat會被自動添加監聽。另外一種情況是被人來主動發消息,這個時候就要把監聽加在ChatManager上。我在使用過程中發現使用第一種方法時有時會出現不能監聽到消息的情況,但是用第二種方法就沒有問題。

 

ChatManager().addChatListener(new ChatManagerListener() {
        
         @Override
         public void chatCreated(Chat chat, boolean createdLocally) {
            //這個方法中如果是之前還沒有和該聯繫人聊天,那麼
	    // createdLocally的值是false,如果已經在聊了那麼是true。
            //所以如果是false,那麼就要建立新的聊天,如果是true,
             //則將消息轉給已經打開的窗口即可
         }
      });
 }
 

 

第二個問題是如何獲得聯繫人列表,smack的聯繫人都封裝在Roster類中。Roster可以有兩種方式來得到聯繫人,一種是先得到分組的聯繫人。首先要得到分組列表,然後在每個組中得到聯繫人。

 

groups = roster.getGroups();
      LogTools.INFO("創建分組中!");
      for(RosterGroup group : groups){
         LogTools.INFO("創建了分組:"+group.getName());
         entries = group.getEntries();
         for(RosterEntry entry : entries){
            LogTools.INFO("創建了好友列表: "+entry.getUser());
         }
      }

 

 

第二種方法是直接得到聯繫人,不分組的。

那麼直接就是

 

Collection<RosterEntry> entries = roster.getEntries();
        for(RosterEntry entry : entries){
          System.out.println("用戶列表:"+entry.getName());
        }

 

 

 

其他的網上的介紹還是挺詳細的。先總結這些,還在研究如何擴充smack的視頻通信。以後再和大家分享。

下面是根據網上的一個具體例子,可以給大家參考。

 

import java.util.Collection;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;

public class XmppManager {
    
    private static final int packetReplyTimeout = 500; // millis
    
    private String server;
    private int port;
    
    private ConnectionConfiguration config;
    private XMPPConnection connection;

    private ChatManager chatManager;
    private MessageListener messageListener;
    private Chat chat;
    
    public XmppManager(String server, int port) {
        this.server = server;
        this.port = port;
    }
    
    public void init() throws XMPPException {
        
        System.out.println(String.format("Initializing connection to server %1$s port %2$d", server, port));

        SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);
        
        config = new ConnectionConfiguration(server, port,"serverName.com");
        System.out.println("連接成功:");
        config.setSASLAuthenticationEnabled(true);
        config.setSecurityMode(SecurityMode.enabled);
        System.out.println("config設置成功!");
        connection = new XMPPConnection(config);
        connection.connect();
        
        System.out.println("Connected: " + connection.isConnected());
        
        chatManager = connection.getChatManager();
        messageListener = new MyMessageListener();
    }
    
    public void performLogin(String username, String password) throws XMPPException {
    	System.out.println("連接對象的值:"+connection+"是否已經連接的判斷:"+connection.isConnected());
        if (connection!=null && connection.isConnected()) {
            System.out.println("登錄部分的代碼執行了");
            connection.login(username, password);

        }
    }

    public void setStatus(boolean available, String status) {
        
        Presence.Type type = available? Type.available: Type.unavailable;
        Presence presence = new Presence(type);
        
        presence.setStatus(status);
        connection.sendPacket(presence);
        
    }
    
    public void destroy() {
        if (connection!=null && connection.isConnected()) {
            connection.disconnect();
        }
    }
    
    public void sendMessage(String message, String buddyJID) throws XMPPException {
        System.out.println(String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
        chat = chatManager.createChat(buddyJID, messageListener);
        chat.sendMessage(message);
    }
    
    public void createEntry(String user, String name) throws Exception {
        System.out.println(String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
        Roster roster = connection.getRoster();
        
        roster.createEntry(user, name, null);
    }
    
    class MyMessageListener implements MessageListener {

        @Override
        public void processMessage(Chat chat, Message message) {
        	System.out.println("收到消息!");
            String from = message.getFrom();
            String body = message.getBody();
            System.out.println(String.format("Received message '%1$s' from %2$s", body, from));
        }
        
    }
    
}
 

 

 

public class XmppTest {
    
    public static void main(String[] args) throws Exception {
        
        String username = "[email protected]";
        String password = "your password";

        
        XmppManager xmppManager = new XmppManager("serverName.com", 5222);
        System.out.println("連接服務器成功!");
        xmppManager.init();
        System.out.println("初始化成功!");
        xmppManager.performLogin(username, password);
        System.out.println("登錄成功!");
       
        xmppManager.setStatus(true, "Hello everyone");
        
        String buddyJID = "[email protected]";
        String buddyName = "friend";
        xmppManager.createEntry(buddyJID, buddyName);
        
        xmppManager.sendMessage("Hello mate", "[email protected]");
        System.out.println("發送消息成功!");
        boolean isRunning = true;
        
        while (isRunning) {
            Thread.sleep(50);
        }
        
        xmppManager.destroy();
        
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章