基于Smack3.0.4+ Openfire3.10.2下学习开发IM(五)聊天室操作:创建聊天室、成员添加聊天室、查询聊天室成员和监听聊天室

本文详细介绍了如何使用Openfire作为服务器和SmackAPI库实现即时消息(IM)聊天室功能,包括创建聊天室、成员加入、查询成员、监听聊天室消息等操作。

以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了。后来在网上看到用openfire做服务器,利用强大的Smack API库来实现IM聊天就简单多了。 

网上也有很多关于这方面的资料,我就在这里把网上的资料和自己的理解总结一下和大家一起交流学习。

需要用到以下几个工具:

Openfire  最新版本(openfire 3.10.2) 

下载地址:http://www.igniterealtime.org/downloads/index.jsp

安装配置可参考:http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html

Smack 最新版本(Smack4.1.4,而我选用的Smack是3.0.4版本)

下载地址:http://www.igniterealtime.org/downloads/index.jsp


需要安装的安装好,需要下载的下载好(这里就不多作介绍)。创建项目工程,导入Smack jar包,OK,下面就一起去学习聊天室操作:创建聊天室、成员添加聊天室、查询聊天室成员和监听聊天室等一些功能!

首先第一、与服务器建立好连接

关键代码:zhou_pc为服务器IP,5222为服务器端口号

package com.openfire.util;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;

public class SmackConnectionUtil {
	private static XMPPConnection connection = null;

	public static XMPPConnection getInstance(String serverName, int port) {
		if (connection == null) {
			ConnectionConfiguration config = new ConnectionConfiguration(serverName, port);
			config.setSASLAuthenticationEnabled(false);
			connection = new XMPPConnection(config);

		}
		return connection;
	}

}
二、创建聊天室

/** 
     * 创建房间 
     *  
     * @param roomName 房间名称 
     */  
    public static void createRoom(XMPPConnection connection,String roomName) {  
      
        try {  
            // 创建一个MultiUserChat  
            MultiUserChat muc = new MultiUserChat(connection, roomName  
                    + "@conference." + connection.getServiceName());  
         // 创建聊天室 
            muc.create(roomName); 
            // 获得聊天室的配置表单 
            Form form = muc.getConfigurationForm(); 
            // 根据原始表单创建一个要提交的新表单。 
            Form submitForm = form.createAnswerForm(); 
            // 向要提交的表单添加默认答复 
            for (Iterator fields = form.getFields(); fields.hasNext();) { 
                FormField field = (FormField) fields.next(); 
                if (!FormField.TYPE_HIDDEN.equals(field.getType()) 
            && field.getVariable() != null) { 
                    // 设置默认值作为答复 
                    submitForm.setDefaultAnswer(field.getVariable()); 
                } 
            } 
            // 设置聊天室的新拥有者 
            // List owners = new ArrayList(); 
            // owners.add("liaonaibo2\\40slook.cc"); 
            // owners.add("liaonaibo1\\40slook.cc"); 
            // submitForm.setAnswer("muc#roomconfig_roomowners", owners); 
            // 设置聊天室是持久聊天室,即将要被保存下来 
            submitForm.setAnswer("muc#roomconfig_persistentroom", true); 
            // 房间仅对成员开放 
            submitForm.setAnswer("muc#roomconfig_membersonly", false); 
            // 允许占有者邀请其他人 
            submitForm.setAnswer("muc#roomconfig_allowinvites", true); 
            // 能够发现占有者真实 JID 的角色 
            // submitForm.setAnswer("muc#roomconfig_whois", "anyone"); 
            // 登录房间对话 
            submitForm.setAnswer("muc#roomconfig_enablelogging", true); 
            // 仅允许注册的昵称登录 
            submitForm.setAnswer("x-muc#roomconfig_reservednick", true); 
            // 允许使用者修改昵称 
            submitForm.setAnswer("x-muc#roomconfig_canchangenick", false); 
            // 允许用户注册房间 
            submitForm.setAnswer("x-muc#roomconfig_registration", false); 
            // 发送已完成的表单(有默认值)到服务器来配置聊天室 
            muc.sendConfigurationForm(submitForm); 
            System.out.println("创建会议室成功!!!!!");
        } catch (XMPPException e) {  
            e.printStackTrace();  
        }  
    }  
相关截图:


三、加入聊天室

 /** 
     * 加入会议室 
     *  
     * @param user 昵称 
     * @param password 会议室密码 
     * @param roomsName 会议室名 
     * @param connection  
     */  
    public static MultiUserChat joinMultiUserChat(String user, String password, String roomsName,  
            XMPPConnection connection) {  
        try {  
            // 使用XMPPConnection创建一个MultiUserChat窗口  
            MultiUserChat muc = new MultiUserChat(connection, roomsName  
                    + "@conference." + connection.getServiceName());  
            // 聊天室服务将会决定要接受的历史记录数量  
            DiscussionHistory history = new DiscussionHistory();  
                history.setMaxStanzas(0);  
                        //history.setSince(new Date());  
            // 用户加入聊天室  
                muc.join(user, password, history, SmackConfiguration.getPacketReplyTimeout());  
            System.out.println("会议室加入成功........");  
            return muc;  
        } catch (XMPPException e) {  
            e.printStackTrace();  
            System.out.println("会议室加入失败........");  
            return null;  
        }  
    }  
    
相关截图:


四、查询会议室中的所有成员

注意:这里查询出来的名字只是用户进入会议室所用的昵称

/** 
     * 查询会议室成员名字 
     * @param muc 
     */  
    public static List<String> findMulitUser(MultiUserChat muc){  
        List<String> listUser = new ArrayList<String>();  
        Iterator<String> it = muc.getOccupants();  
        //遍历出聊天室人员名称  
        while (it.hasNext()) {  
            // 聊天室成员名字  
            String name = StringUtils.parseResource(it.next());  
            listUser.add(name);  
        }  
        return listUser;  
    }  

五、 获取服务器上所有会议室

  /** 
     * 获取服务器上所有会议室 
     * @return 
     * @throws XMPPException 
     */  
    public static void getConferenceRoom(XMPPConnection connection) throws XMPPException {  
      
        new ServiceDiscoveryManager(connection);  
        if (!MultiUserChat.getHostedRooms(connection,  
                connection.getServiceName()).isEmpty()) {  
  
            for (HostedRoom k : MultiUserChat.getHostedRooms(connection,  
                    connection.getServiceName())) {  
  
                for (HostedRoom j : MultiUserChat.getHostedRooms(connection,  
                        k.getJid())) {  
                    RoomInfo info2 = MultiUserChat.getRoomInfo(connection,  
                            j.getJid());  
                    if (j.getJid().indexOf("@") > 0) {  
  
                     
                        System.out.println(j.getName());//聊天室的名称  
                        System.out.println(j.getJid());//聊天室JID  
                        System.out.println(info2.getOccupantsCount());//聊天室中占有者数量  
                        System.out.println(info2.getDescription());//聊天室的描述  
                        System.out.println(info2.getSubject());//聊天室的主题  
                       
                    }  
                }  
            }  
        }  
       
    }  

相关截图:


六、监听会议室的消息

添加会议室消息监听(RoomTest.java) :

	try{
					connection.connect();
					connection.login("wangzheng", "123456");
					 // 创建一个MultiUserChat  
		            MultiUserChat multiChat = new MultiUserChat(connection, "ssh"  
		                    + "@conference." + connection.getServiceName());	  
		           
		            multiChat.addMessageListener(new MultiListener());
				}catch(Exception e){
					e.printStackTrace();
				}

package com.openfire.listener;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

public class MultiListener implements PacketListener {
	/** 
     * 聊天室监听事件 
     *  
     * @author Administrator 
     *  
     */  
	 @Override  
     public void processPacket(Packet packet) {  
         Message message = (Message) packet;  
         // 接收来自聊天室的聊天信息  
         String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());  
//         MucHistory mh = new MucHistory();  
//         mh.setUserAccount(account);  
         String from = StringUtils.parseResource(message.getFrom());  
         String fromRoomName = StringUtils.parseName(message.getFrom());  
         System.out.println(fromRoomName);  
         System.out.println(from);  
         System.out.println(message.getBody());  
         System.out.println(time);  
         

     }  

}

七、发送会议室消息

会议室消息发送(RoomTest.java) :

		connection.connect();
					connection.login("wangzheng", "123456");
					 // 创建一个MultiUserChat  
		            MultiUserChat multiChat = new MultiUserChat(connection, "ssh"  
		                    + "@conference." + connection.getServiceName());		          
		            Message str=new Message();
		            str.setBody("Hello Xmpp服务器1");
		            multiChat.sendMessage(str);

八、监听会议室状态(成员的进入、离开等)

添加监听事件(RoomTest.java):

		try{
					connection.connect();
					connection.login("wangzheng", "123456");
					RoomUtil.joinMultiUserChat("admin", null, "ssh", connection);
					 // 创建一个MultiUserChat  
		            MultiUserChat multiChat = new MultiUserChat(connection, "ssh"  
		                    + "@conference." + connection.getServiceName());
		         
		            multiChat.addParticipantStatusListener(new ParticipantStatus());  
				}catch(Exception e){
					e.printStackTrace();
				}
会议室状态监听事件:
package com.openfire.listener;

import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.ParticipantStatusListener;

public class ParticipantStatus implements ParticipantStatusListener  {
	 @Override  
     public void adminGranted(String arg0) {  
         // TODO Auto-generated method stub  
		 System.out.println(StringUtils.parseResource(arg0)+ " adminGranted.");  
     }  

     @Override  
     public void adminRevoked(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " adminRevoked."); 
     }  

     @Override  
     public void banned(String arg0, String arg1, String arg2) {  
         // TODO Auto-generated method stub  

     }  

     @Override  
     public void joined(String participant) {  
         System.out.println(StringUtils.parseResource(participant)+ " has joined the room.");  
     }  

     @Override  
     public void kicked(String arg0, String arg1, String arg2) {  
         // TODO Auto-generated method stub  

     }  

     @Override  
     public void left(String participant) {  
         // TODO Auto-generated method stub  
         System.out.println(StringUtils.parseResource(participant)+ " has left the room.");  
           
     }  

     @Override  
     public void membershipGranted(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " membershipGranted.");
     }  

     @Override  
     public void membershipRevoked(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " membershipRevoked.");
     }  

     @Override  
     public void moderatorGranted(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " moderatorGranted.");
     }  

     @Override  
     public void moderatorRevoked(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " moderatorRevoked.");
     }  

     @Override  
     public void nicknameChanged(String participant, String newNickname) {  
         System.out.println(StringUtils.parseResource(participant)+ " is now known as " + newNickname + ".");  
     }  

     @Override  
     public void ownershipGranted(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " ownershipGranted.");
     }  

     @Override  
     public void ownershipRevoked(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " ownershipRevoked.");
     }  

     @Override  
     public void voiceGranted(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " voiceGranted.");
     }  

     @Override  
     public void voiceRevoked(String arg0) {  
         // TODO Auto-generated method stub  
    	 System.out.println(StringUtils.parseResource(arg0)+ " voiceRevoked.");
     }  

}


 源码下载,待相关代码整理完毕,再发布地址。



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值