通过smack client + openfire server 实现 peer to peer communication

【0】README
1)本文旨在 给出源代码 实现 smack client + openfire server 实现 peer to peer communication
2)当然,代码中用到的 user 和 pass, 你需要事先在 openfire 里面注册;
3)also , you can checkout the source code  from   
Attention)要区分 ChatManagerListener and ChatMessageListener, 这两个监听器,它们的功能是不同的,但是长相却十分相似;



【2】代码如下 
package com.xmpp.client;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Set;

import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Body;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.delay.packet.DelayInformation;

// this class encapsulates some info for
// connection, login, creating chat.
public class UserChatBase { // smakc client base class.
	private XMPPTCPConnectionConfiguration conf;
	private AbstractXMPPConnection connection;
	private ChatManager chatManager;
	private Chat chat;
	
	/**
	 * @param args refers to an array with ordered values as follows: user, password, host, port.
	 */
	public UserChatBase(String... args) {
		String username = args[0];
		String password = args[1];

		conf = XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(username, password)
				.setServiceName(MyConstants.HOST)
				.setHost(MyConstants.HOST)
				.setPort(Integer.valueOf(MyConstants.PORT))
				.setSecurityMode(SecurityMode.disabled) // (attention of this line about SSL authentication.)
				.build();
		connection = new XMPPTCPConnection(conf);
		chatManager = ChatManager.getInstanceFor(connection);
		// differentiation ChatManagerListener from ChatMessageListener
		chatManager.addChatListener(new MyChatListener(this));
	}
	
	/**
	 * connect to and login in openfire server.
	 * @throws XMPPException 
	 * @throws IOException 
	 * @throws SmackException 
	 */
	public void connectAndLogin() throws SmackException, IOException, XMPPException {
		System.out.println("executing connectAndLogin method.");
		System.out.println("connection = " + connection);
		connection.connect();
		System.out.println("successfully connection.");
		connection.login(); // client logins into openfire server.
		System.out.println("successfully login.");
	}
	
	/**
	 * disconnect to and logout from openfire server.
	 * @throws XMPPException 
	 * @throws IOException 
	 * @throws SmackException 
	 */
	public void disconnect() {
		System.out.println("executing disconnect method.");
		try {
			connection.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * create chat instance using ChatManager.
	 */
	public Chat createChat(String toUser) {		
		toUser += "@" + MyConstants.HOST;
		chat = chatManager.createChat(toUser);		
		
		// create the chat with specified user.(startup a thread)
		MessageHandler handler = new MessageHandler(chat); 
		MessageHandler.Sender sender = handler.new Sender(); // creating inner class.
		new Thread(sender).start();
		// creating thread over.
		
		return chat;
	}
	
	/**
	 * get chat timestamp, also time recoded when the msg starts to send.
	 * @param msg 
	 * @return timestamp.
	 */
	public String getChatTimestamp(Message msg) {
		ExtensionElement delay = DelayInformation.from(msg);
		
		if(delay == null) {
			return null;
		}
		Date date = ((DelayInformation) delay).getStamp();
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
		return format.format(date);
	}

	public XMPPTCPConnectionConfiguration getConf() {
		return conf;
	}

	public AbstractXMPPConnection getConnection() {
		return connection;
	}

	public ChatManager getChatManager() {
		return chatManager;
	}

	public Chat getChat() {
		return chat;
	}
}
package com.xmpp.client;

import java.util.Locale;

public class ClientA { // one client 
	public static void main(String a[]) throws Exception {
		Locale.setDefault(Locale.CHINA);
		UserChatBase client = new UserChatBase(
				new String[]{"tangtang", "tangtang"});
		
		client.connectAndLogin();
		System.out.println("building connection between tangtang as sender and pacoson as receiver.");
		// create the chat with specified user.(startup a thread)
		client.createChat("pacoson");
	}
}
package com.xmpp.client;

import java.util.Locale;

public class ClientB { // another client.
	public static void main(String a[]) throws Exception {
		Locale.setDefault(Locale.CHINA);
		UserChatBase client = new UserChatBase(
				new String[]{"pacoson", "pacoson"});
		
		client.connectAndLogin();
		System.out.println("building connection between pacoson as sender and tangtang as receiver.");
		// create the chat with specified user.(startup a thread)
		client.createChat("tangtang");
	}
}
package com.xmpp.client;

import java.util.Set;

import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManagerListener;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Body;

// 监听器
public class MyChatListener implements ChatManagerListener{
	private UserChatBase client;
	
	public MyChatListener(UserChatBase client) {
		this.client = client;
	}
	
	@Override
	public void chatCreated(Chat chat, boolean createdLocally) {
		if (!createdLocally) {
			chat.addMessageListener(new ChatMessageListener() {
				@Override
				public void processMessage(Chat chat, Message message) {
					String from = message.getFrom();
					Set<Body> bodies = message.getBodies();
					String timestamp = client.getChatTimestamp(message);
					
					if(timestamp != null) {
						System.out.println(timestamp);
					}
					for(Body b : bodies) {
						System.out.println(from + ":" + b.getMessage());
					}
				}
			});
		}
	}
}
package com.xmpp.client;

public class MyConstants { // 常量类
	public static final int PORT = 5222;
	public static final String HOST = "lenovo-pc";
	public static final String PLUGIN_PRESENT_URL
		= "http://lenovo-pc:9090/plugins/presence/status?";
		//= "http://lenovo-pc:9090/plugins/presence/status?jid=pacoson@lenovo-pc&type=text&req_jid=tangtang@lenovo-pc";
	
	public static final String buildPresenceURL(String from, String to, String type) {
		return PLUGIN_PRESENT_URL 
				+ "jid=" + to + "@" + HOST + "&"
				+ "req_jid=" + from + "@" + HOST + "&"
				+ "type=" + type;
	}
}
package com.xmpp.client;

import java.util.Scanner;

import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.chat.Chat;

// 创建发送msg 线程.
public class MessageHandler {
	private Chat chat;
	
	public MessageHandler(Chat chat) {
		this.chat = chat;
	}

	class Sender implements Runnable{
		/*public Sender(Chat chat) {
			MessageHandler.this.chat = chat;
		}*/
		public Sender() {}
		
		@Override
		public void run() {
			Scanner scanner = new Scanner(System.in);
			while(scanner.hasNext()) {
				String line = scanner.nextLine();
				try {
					chat.sendMessage(line);
				} catch (NotConnectedException e) {
					e.printStackTrace();
					break;
				}
			}
		} 
	}
	
	class Receiver {
		
	}
}
(干货——只有当 消息接收者处于离线的时候,其接收到的消息才会封装 delay 元素,其属性有 stamp 记录了 msg 发送的时间。(also, you can refer to https://community.igniterealtime.org/thread/22791

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值