【0】README
1)本文旨在 给出源代码 实现 smack client + openfire server 实现 peer to peer communication
2)当然,代码中用到的 user 和 pass, 你需要事先在 openfire 里面注册;
3)also , you can checkout the source code  from   
https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaSupplement/smack-client ;
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 ChatMessageListenerchatManager.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;}@Overridepublic void chatCreated(Chat chat, boolean createdLocally) {if (!createdLocally) {chat.addMessageListener(new ChatMessageListener() {@Overridepublic 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() {}@Overridepublic 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))

通过smack client + openfire server 实现 peer to peer communication相关推荐

  1. iOS 中client和server的 Web Service 网络通信 (1)

    当你打开你手机上新浪微博应用或者知乎应用是.你是否会去想这些显示在手机上的图片和数据时从哪里来的?又是通过如何的方法实现的?好.那么接下来就介绍是如何实现的.过程又是怎么样的.      当我们浏览着 ...

  2. Openfire Server presence(在线状态)消息处理流程

    Openfire Server presence(在线状态)消息处理流程 Presence处理是IM Server的核心,也是一个IM Server最复杂的部分.一个用户的状态发生变化,需要通过服务器 ...

  3. 【异常】 Ensure that config phoenix.schema.isNamespaceMappingEnabled is consistent on client and server.

    [异常] Ensure that config phoenix.schema.isNamespaceMappingEnabled is consistent on client and server. ...

  4. 带入gRPC:gRPC Streaming, Client and Server

    带入gRPC:gRPC Streaming, Client and Server 原文地址:带入gRPC:gRPC Streaming, Client and Server 项目地址:go-grpc- ...

  5. Java -- 网络编程(一):Client与Server之间的数据传送

    目前对于我这种刚接触网络编程的豆芽来说,对网络编程最直观的了解就是:一些的Client和一个Server端之间的数据传递.具体当然是复杂的,但是那是我以后要学的. 今天我知道了可以通过Socket和D ...

  6. jvm的client与server工作模式

    [README] JVM Server模式与client模式启动,最主要的差别在于: -Server模式启动时,速度较慢,但是一旦运行起来后,性能将会有很大的提升. 原因是:当虚拟机运行在-clien ...

  7. jvm 参数-server_JVM选项:-client vs -server

    jvm 参数-server 您是否曾经在运行Java应用程序时想知道-client或-server开关是什么? 例如: javaw.exe -client com.blogspot.sdoulger. ...

  8. JVM选项:-client vs -server

    您是否曾经在运行Java应用程序时想知道-client或-server开关是什么? 例如: javaw.exe -client com.blogspot.sdoulger.LoopTest 也显示在j ...

  9. Ensure that config phoenix.schema.isNamespaceMappingEnabled is consistent on client and server

    Phoenix链接异常,报错如下 0: jdbc:phoenix:xxx:2181:/hbase> Error: ERROR 726 (43M10): Inconsistent namespac ...

最新文章

  1. windows下命令行启动tomcat
  2. 使用NTDSXtract离线抓取Domain Hash
  3. iOS Swift GCD 开发教程
  4. 汇编语言王爽第二版-课后答案以及解析
  5. mysql 嵌入式_MySql移植到嵌入式Linux平台
  6. ceph集群报 Monitor clock skew detected 错误问题排查,解决
  7. 前端学习(3144):react-hello-react之对比新旧周期
  8. Linq to Sql : 三种事务处理方式
  9. iOS7应用开发6:UINavigation, UITabbar控制器的多态性
  10. plsql developer 查看存储过程执行计划_产品简介 | X-Developer一站式研发效能管理平台...
  11. Laravel 大将之 路由 模块
  12. canvas绘图粒子扩散效果【原创】
  13. 聚类-----高斯混合模型
  14. 程序员、技术主管和架构师
  15. MapReduce: 大规模集群上的简化数据处理
  16. Excel 筛选唯一值或删除重复值
  17. Mac上怎么把mov文件转成gif文件
  18. 云计算HCIA学习笔记-云计算基础概念
  19. 软件设计模式从何而来?------“抄袭来的” 设计模式
  20. RNA-seq的典型流程(protocol)

热门文章

  1. P6348 [PA2011]Journeys 线段树优化建图 区间连区间
  2. SP10707 COT2 - Count on a tree II
  3. 牛客题霸 [栈和排序] C++题解/答案
  4. 201403-5 任务调度
  5. [2021-06-19] 提高组新手副本Ⅱ(联网,欧几里得,分解树,开关灯)
  6. P8215-[THUPC2022 初赛]分组作业【网络流】
  7. YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】
  8. jzoj4229-学习神技【逆元,费马小定理】
  9. 【2018.3.17】模拟赛之四-ssl1864jzoj1368 燃烧木棒【最短路,Floyd】
  10. 初一模拟赛总结(2019.3.9)