XMPP即时通讯协议使用(二)——基于Smack相关操作

package com.test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jivesoftware.smackx.pubsub.PayloadItem;
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.packet.Message;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterGroup;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.iqregister.AccountManager;
import org.jivesoftware.smackx.pubsub.AccessModel;
import org.jivesoftware.smackx.pubsub.ConfigureForm;
import org.jivesoftware.smackx.pubsub.Item;
import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jivesoftware.smackx.pubsub.PublishModel;
import org.jivesoftware.smackx.pubsub.SimplePayload;
import org.jivesoftware.smackx.pubsub.SubscribeForm;
import org.jivesoftware.smackx.pubsub.Subscription;
import org.jivesoftware.smackx.vcardtemp.packet.VCard;
import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Localpart;

public class SmarkUtil {

	private XMPPTCPConnection connection;

	private String userName;

	private String password;

	private String xmppDomain;

	private String serverName;

	public SmarkUtil(String userName, String password, String xmppDomain, String serverName) {
		this.userName = userName;
		this.password = password;
		this.xmppDomain = xmppDomain;
		this.serverName = serverName;
		try {
			if (connection == null) {
				getConnection(userName, password, xmppDomain, serverName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取连接
	 * 
	 * @param userName
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public void getConnection(String userName, String password, String xmppDomain, String serverName) throws Exception {
		try {
			XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration
					.builder();
			configBuilder.setHost(xmppDomain);
			configBuilder.setPort(5222);
			configBuilder.setUsernameAndPassword(userName, password);
			configBuilder.setXmppDomain(xmppDomain);
			configBuilder.setSendPresence(true);
			configBuilder
					.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled);

			connection = new XMPPTCPConnection(configBuilder.build());
			// 连接服务器
			connection.connect();
			// 登录服务器
			connection.login();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建一个新用户
	 * 
	 * @param userName
	 *            用户名
	 * @param password
	 *            密码
	 * @param attr
	 *            用户资料
	 * @return
	 * @throws Exception
	 */
	public boolean registerAccount(String userName, String password, Map attr) throws Exception {
		AccountManager manager = AccountManager.getInstance(connection);
		manager.sensitiveOperationOverInsecureConnection(true);
		Localpart l_username = Localpart.from(userName);
		if (attr == null) {
			manager.createAccount(l_username, password);
		} else {
			manager.createAccount(l_username, password, attr);
		}

		return true;
	}

	/**
	 * 修改当前登陆用户密码
	 * 
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public boolean changePassword(String password) throws Exception {
		AccountManager manager = AccountManager.getInstance(connection);
		manager.sensitiveOperationOverInsecureConnection(true);
		manager.changePassword(password);
		return true;
	}

	/**
	 * 删除当前登录用户
	 * 
	 * @return
	 * @throws Exception
	 */
	public boolean deleteAccount() throws Exception {
		AccountManager manager = AccountManager.getInstance(connection);
		manager.sensitiveOperationOverInsecureConnection(true);
		manager.deleteAccount();
		return true;
	}

	/**
	 * 获取用户属性名称
	 * 
	 * @return
	 * @throws Exception
	 */
	public List getAccountInfo() throws Exception {
		List list = new ArrayList();
		AccountManager manager = AccountManager.getInstance(connection);
		manager.sensitiveOperationOverInsecureConnection(true);
		Set set = manager.getAccountAttributes();
		list.addAll(set);
		return list;
	}

	/**
	 * 获取所有组
	 * 
	 * @return
	 * @throws Exception
	 */
	public List getGroups() throws Exception {
		List grouplist = new ArrayList();
		Roster roster = Roster.getInstanceFor(connection);
		Collection rosterGroup = roster.getGroups();
		Iterator i = rosterGroup.iterator();
		while (i.hasNext()) {
			grouplist.add(i.next());
		}
		return grouplist;
	}

	/**
	 * 添加分组
	 * 
	 * @param groupName
	 * @return
	 * @throws Exception
	 */
	public boolean addGroup(String groupName) throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		roster.createGroup(groupName);
		return true;

	}

	/**
	 * 获取指定分组的好友
	 * 
	 * @param groupName
	 * @return
	 * @throws Exception
	 */
	public List getEntriesByGroup(String groupName) throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		List Entrieslist = new ArrayList();
		RosterGroup rosterGroup = roster.getGroup(groupName);
		Collection rosterEntry = rosterGroup.getEntries();
		Iterator i = rosterEntry.iterator();
		while (i.hasNext()) {
			Entrieslist.add(i.next());
		}
		return Entrieslist;
	}

	/**
	 * 获取全部好友
	 * 
	 * @return
	 * @throws Exception
	 */
	public List getAllEntries() throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		List Entrieslist = new ArrayList();
		Collection rosterEntry = roster.getEntries();
		Iterator i = rosterEntry.iterator();
		while (i.hasNext()) {
			Entrieslist.add(i.next());
		}
		return Entrieslist;
	}

	/**
	 * 获取用户VCard信息
	 * 
	 * @param userName
	 * @return
	 * @throws Exception
	 */
	public VCard getUserVCard(String userName) throws Exception {
		VCard vcard = new VCard();
		EntityBareJid jid = JidCreate.entityBareFrom(userName + "@" + this.serverName);
		vcard.load(connection, jid);
		return vcard;
	}

	/**
	 * 添加好友 无分组
	 * 
	 * @param userName
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public boolean addUser(String userName, String name) throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		EntityBareJid jid = JidCreate.entityBareFrom(userName + "@" + this.serverName);
		roster.createEntry(jid, name, null);
		return true;

	}

	/**
	 * 添加好友 有分组
	 * 
	 * @param userName
	 * @param name
	 * @param groupName
	 * @return
	 * @throws Exception
	 */
	public boolean addUser(String userName, String name, String groupName) throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		EntityBareJid jid = JidCreate.entityBareFrom(userName + "@" + this.serverName);
		roster.createEntry(jid, name, new String[] { groupName });
		return true;

	}

	/**
	 * 删除好友
	 * 
	 * @param userName
	 * @return
	 * @throws Exception
	 */
	public boolean removeUser(String userName) throws Exception {
		Roster roster = Roster.getInstanceFor(connection);
		EntityBareJid jid = JidCreate.entityBareFrom(userName + "@" + this.serverName);
		RosterEntry entry = roster.getEntry(jid);
		System.out.println("删除好友:" + userName);
		System.out.println("User." + roster.getEntry(jid) == null);
		roster.removeEntry(entry);

		return true;

	}

	/**
	 * 创建发布订阅节点
	 * 
	 * @param nodeId
	 * @return
	 * @throws Exception
	 */
	public boolean createPubSubNode(String nodeId) throws Exception {
		PubSubManager mgr = PubSubManager.getInstance(connection);
		// Create the node
		LeafNode leaf = mgr.createNode(nodeId);
		ConfigureForm form = new ConfigureForm(DataForm.Type.submit);
		form.setAccessModel(AccessModel.open);
		form.setDeliverPayloads(true);
		form.setNotifyRetract(true);
		form.setPersistentItems(true);
		form.setPublishModel(PublishModel.open);
		form.setMaxItems(10000000);// 设置最大的持久化消息数量

		leaf.sendConfigurationForm(form);
		return true;
	}

	/**
	 * 创建发布订阅节点
	 * 
	 * @param nodeId
	 * @param title
	 * @return
	 * @throws Exception
	 */
	public boolean createPubSubNode(String nodeId, String title) throws Exception {
		PubSubManager mgr = PubSubManager.getInstance(connection);
		// Create the node
		LeafNode leaf = mgr.createNode(nodeId);
		ConfigureForm form = new ConfigureForm(DataForm.Type.submit);
		form.setAccessModel(AccessModel.open);
		form.setDeliverPayloads(true);
		form.setNotifyRetract(true);
		form.setPersistentItems(true);
		form.setPublishModel(PublishModel.open);
		form.setTitle(title);
		form.setBodyXSLT(nodeId);
		form.setMaxItems(10000000);// 设置最大的持久化消息数量
		form.setMaxPayloadSize(1024*12);//最大的有效载荷字节大小
		leaf.sendConfigurationForm(form);
		return true;
	}

	public boolean deletePubSubNode(String nodeId) throws Exception {
		PubSubManager mgr = PubSubManager.getInstance(connection);
		mgr.deleteNode(nodeId);
		return true;
	}

	/**
	 * 发布消息
	 * 
	 * @param nodeId
	 *            主题ID
	 * @param eventId
	 *            事件ID
	 * @param messageType
	 *            消息类型:publish(发布)/receipt(回执)/state(状态)
	 * @param messageLevel
	 *            0/1/2
	 * @param messageSource
	 *            消息来源
	 * @param messageCount
	 *            消息数量
	 * @param packageCount
	 *            总包数
	 * @param packageNumber
	 *            当前包数
	 * @param createTime
	 *            创建时间 2018-06-07 09:43:06
	 * @param messageContent
	 *            消息内容
	 * @return
	 * @throws Exception
	 */
	public boolean publish(String nodeId, String eventId, String messageType, int messageLevel, String messageSource,
			int messageCount, int packageCount, int packageNumber, String createTime, String messageContent)
			throws Exception {

		if (messageContent.length() > 1024 * 10) {
			throw new Exception("消息内容长度超出1024*10,需要进行分包发布");
		}
		PubSubManager mgr = PubSubManager.getInstance(connection);
		LeafNode node = null;

		node = mgr.getNode(nodeId);

		StringBuffer xml = new StringBuffer();
		xml.append("");
		xml.append("" + nodeId + "");
		xml.append("" + eventId + "");
		xml.append("" + messageType + "");
		xml.append("" + messageLevel + "");
		xml.append("" + messageSource + "");
		xml.append("" + messageCount + "");
		xml.append("" + packageCount + "");
		xml.append("" + packageNumber + "");
		xml.append("" + createTime + "");
		xml.append("" + messageContent + "");
		xml.append("");

		SimplePayload payload = new SimplePayload("pubmessage", "pub:message", xml.toString().toLowerCase());
		PayloadItem item = new PayloadItem(System.currentTimeMillis() + "", payload);
		node.publish(item);
		return true;
	}

	/**
	 * 订阅主题
	 * 
	 * @param nodeId
	 * @return
	 * @throws Exception
	 */
	public boolean subscribe(String nodeId) throws Exception {

		PubSubManager mgr = PubSubManager.getInstance(connection);

		// Get the node
		LeafNode node = mgr.getNode(nodeId);
		SubscribeForm subscriptionForm = new SubscribeForm(DataForm.Type.submit);
		subscriptionForm.setDeliverOn(true);
		subscriptionForm.setDigestFrequency(5000);
		subscriptionForm.setDigestOn(true);
		subscriptionForm.setIncludeBody(true);

		List subscriptions = node.getSubscriptions();

		boolean flag = true;
		for (Subscription s : subscriptions) {
			if (s.getJid().toLowerCase().equals(connection.getUser().asEntityBareJidString().toLowerCase())) {// 已订阅过
				flag = false;
				break;
			}
		}
		if (flag) {// 未订阅,开始订阅
			node.subscribe(userName + "@" + this.serverName, subscriptionForm);
		}
		return true;
	}

	/**
	 * 获取订阅的全部主题
	 * 
	 * @return
	 * @throws Exception
	 */
	public List querySubscriptions() throws Exception {
		PubSubManager mgr = PubSubManager.getInstance(connection);
		List subs = mgr.getSubscriptions();
		return subs;
	}

	/**
	 * 获取订阅节点的配置信息
	 * 
	 * @param nodeId
	 * @return
	 * @throws Exception
	 */
	public ConfigureForm getConfig(String nodeId) throws Exception {
		PubSubManager mgr = PubSubManager.getInstance(connection);
		LeafNode node = mgr.getNode(nodeId);
		ConfigureForm config = node.getNodeConfiguration();
		return config;
	}

	/**
	 * 获取订阅主题的全部历史消息
	 * 
	 * @return
	 * @throws Exception
	 */
	public List queryHistoryMeassage() throws Exception {
		List result = new ArrayList();
		PubSubManager mgr = PubSubManager.getInstance(connection);
		List subs = mgr.getSubscriptions();
		if (subs != null && subs.size() > 0) {
			for (Subscription sub : subs) {
				String nodeId = sub.getNode();
				LeafNode node = mgr.getNode(nodeId);
				List list = node.getItems();
				result.addAll(list);
			}
		}

		/*
		 * for (Item item : result) { System.out.println(item.toXML()); }
		 */
		return result;
	}

	/**
	 * 获取指定主题的全部历史消息
	 * 
	 * @return
	 * @throws Exception
	 */
	public List queryHistoryMeassage(String nodeId) throws Exception {
		List result = new ArrayList();
		PubSubManager mgr = PubSubManager.getInstance(connection);

		LeafNode node = mgr.getNode(nodeId);
		List list = node.getItems();
		result.addAll(list);

		/*
		 * for (Item item : result) { System.out.println(item.toXML()); }
		 */
		return result;
	}

	/**
	 * 获取指定主题指定数量的历史消息
	 * 
	 * @param nodeId
	 * @param num
	 * @return
	 * @throws Exception
	 */
	public List queryHistoryMeassage(String nodeId, int num) throws Exception {
		List result = new ArrayList();
		PubSubManager mgr = PubSubManager.getInstance(connection);

		LeafNode node = mgr.getNode(nodeId);
		List list = node.getItems(num);
		result.addAll(list);

		/*
		 * for (Item item : result) { System.out.println(item.toXML()); }
		 */
		return result;
	}

	/**
	 * 向指定用户发送消息
	 * 
	 * @param username
	 * @param message
	 * @throws Exception
	 */
	public void sendMessage(String username, String message) throws Exception {
		ChatManager chatManager = ChatManager.getInstanceFor(connection);
		EntityBareJid jid = JidCreate.entityBareFrom(username + "@" + serverName);
		Chat chat = chatManager.createChat(jid);
		Message newMessage = new Message();
		newMessage.setBody(message);
		chat.sendMessage(newMessage);
	}

	/**
	 * 添加聊天消息监听
	 * 
	 * @param chatManagerListener
	 * @throws Exception
	 */
	public void addChatMessageListener(ChatManagerListener chatManagerListener) throws Exception {
		ChatManager chatManager = ChatManager.getInstanceFor(connection);
		chatManager.addChatListener(chatManagerListener);
	}

	/**
	 * 断开连接
	 */
	public void close() {
		connection.disconnect();
	}

}

 


2018-08-28 补充多人聊天相关接口

/**
	 * 创建群聊聊天室
	 *
	 * @param roomName
	 *            聊天室名字
	 * @param nickName
	 *            创建者在聊天室中的昵称
	 * @param password
	 *            聊天室密码
	 * @return
	 */
	public MultiUserChat createChatRoom(String roomName, String nickName, String password) throws Exception {
		MultiUserChat muc;
		try {
			EntityBareJid jid = JidCreate.entityBareFrom(roomName + "@conference." + connection.getServiceName());
			// 创建一个MultiUserChat
			muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
			Resourcepart r = Resourcepart.from(nickName);
			// 创建聊天室
			MucCreateConfigFormHandle isCreated = muc.createOrJoin(r);
			if (true) {
				// 获得聊天室的配置表单
				Form form = muc.getConfigurationForm();
				// 根据原始表单创建一个要提交的新表单。
				Form submitForm = form.createAnswerForm();
				// 向要提交的表单添加默认答复
				List fields = form.getFields();
				for (int i = 0; fields != null && i < fields.size(); i++) {
					if (FormField.Type.hidden != fields.get(i).getType() && fields.get(i).getVariable() != null) {
						// 设置默认值作为答复
						submitForm.setDefaultAnswer(fields.get(i).getVariable());
					}
				}
				// 设置聊天室的新拥有者
				List owners = new ArrayList();
				owners.add(connection.getUser().asEntityBareJidString());// 用户JID
				submitForm.setAnswer("muc#roomconfig_roomowners", owners);
				// 设置聊天室是持久聊天室,即将要被保存下来
				submitForm.setAnswer("muc#roomconfig_persistentroom", true);
				// 房间仅对成员开放
				submitForm.setAnswer("muc#roomconfig_membersonly", false);
				// 允许占有者邀请其他人
				submitForm.setAnswer("muc#roomconfig_allowinvites", true);
				if (password != null && password.length() != 0) {
					// 进入是否需要密码
					submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
					// 设置进入密码
					submitForm.setAnswer("muc#roomconfig_roomsecret", password);
				}
				// 能够发现占有者真实 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);

			}
		} catch (XMPPException e) {
			e.printStackTrace();
			return null;
		}
		return muc;
	}

	/**
	 * 加入聊天室
	 * 
	 * @param roomName
	 * @param nickname
	 * @param password
	 * @throws Exception
	 */
	public MultiUserChat joinMultiUserChat(String roomName, String nickname, String password) throws Exception {
		EntityBareJid jid = JidCreate.entityBareFrom(roomName + "@conference." + connection.getServiceName());
		// 创建一个MultiUserChat
		MultiUserChat muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
		// 聊天室服务将会决定要接受的历史记录数量
		Resourcepart r = Resourcepart.from(nickname);
		muc.join(r);
		return muc;
	}

	/**
	 * 聊天室发送消息
	 * 
	 * @param roomName
	 * @param msg
	 * @throws Exception
	 */
	public void sendMessageMultiUserChat(String roomName, String msg) throws Exception {
		EntityBareJid jid = JidCreate.entityBareFrom(roomName + "@conference." + connection.getServiceName());
		// 创建一个MultiUserChat
		MultiUserChat muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
		muc.sendMessage(msg);
	}

	/**
	 * 获取MultiUserChat
	 * 
	 * @param roomName
	 * @return
	 * @throws Exception
	 */
	public MultiUserChat getMultiUserChat(String roomName) throws Exception {
		EntityBareJid jid = JidCreate.entityBareFrom(roomName + "@conference." + connection.getServiceName());
		// 创建一个MultiUserChat
		MultiUserChat muc = MultiUserChatManager.getInstanceFor(connection).getMultiUserChat(jid);
		return muc;
	}

	/**
	 * 添加聊天室消息监听
	 * 
	 * @param roomName
	 * @param messageListener
	 * @throws Exception
	 */
	public void addMultiUserChatMessageListener(String roomName, MessageListener messageListener) throws Exception {
		MultiUserChat muc = getMultiUserChat(roomName);
		muc.addMessageListener(messageListener);

		/*muc.addMessageListener(new MessageListener() {
			public void processMessage(Message message) { // TODO Auto-generated method stub
				System.out.println(message.getBody());
			}
		});*/

	}

 


更新 2018年9月28日 09:08:06

通过添加

configBuilder.setHost(xmppDomain);
configBuilder.setPort(5222);

解决

九月 28, 2018 9:07:37 上午 org.jivesoftware.smack.util.DNSUtil resolveDomain
信息: Could not resolve DNS SRV resource records for _xmpp-client._tcp.openfire.hylink.net.cn. Consider adding those.

异常

 

你可能感兴趣的:(Java,即时通讯,xmpp,java,web)