XMPP大杂烩

对XMPP的理解

XMPP是基于XML的即时通讯协议。对即时通讯场景进行了高度抽象,比如用订阅对方的上下线状态表示好友。提供了文本通讯、用户上下线通知、联系人管理、群组聊天等功能,还可以安装插件或自行拓展。

服务端的安装

服务端一般用OpenFire。

以macOS为例,官网直接下载安装包,安装完成后,在系统菜单中打开OpenFire控制台,进入OpenFire的Web后台,走完配置向导。数据库可以用OpenFire自带的嵌入式数据库,也可以配置为MySQL。如果是局域网测试的话,主机名最好设置成内网IP。最后一步需要设置管理员密码,管理员的账号是admin。配置完成后,可以登录OpenFire的管理后台。

OpenFire服务器默认开放用户注册、开放建群,所以可以不管OpenFire后台,直接拿来使用。

用户注册

大多XMPP客户端不提供用户注册功能,所以最好在OpenFire后台直接添加用户。试了多个客户端,只有Psi可以成功注册用户,而且登录之后找不到退出的地方,也找不到创建用户的地方。

客户端的选择

XMPP的图形客户端特别多,但是一个比一个难用。在macOS上勉强可以使用的主要有Spark、Adium和Thunderbird。Spark是OpenFire官方提供的客户端,在使用时要注意禁用安全选项,如果主机不受信任的话。

命令行下的客户端,可以使用Profanity

用户登录

登录XMPP账户,需要服务器、用户名、密码三个字段。如果客户端没有提供单独的服务器输入框的话,用户名改用用户名@服务器

Profanity的使用

Profanity不提供用户注册功能,需要先在后台添加用户,或者用其他客户端注册。

  • 登录 /connect 用户名@服务器 tls disable
  • 登出 /disconnect
  • 开启聊天 /msg 用户名@服务器/用户昵称 文本
  • 切换窗口 Alt/Option+数字 Alt+1是系统窗口,其他是聊天窗口
  • 添加用户到通讯录(非好友,不能订阅用户的上下线消息) /roster add 用户名@服务器
  • 添加用户为好友 /sub request 用户名@服务器
  • 收到添加好友请求时允许 /sub allow 用户名@服务器
  • 进入聊天室/群组/房间,不存在则根据向导创建 /join 房间名@服务器
  • 切换在线状态 /away=离开 /online=在线 /dnd=忙碌 ...
  • 退出软件 /quit

Smack的使用

Smack是OpenFire提供的支持XMPP协议的Java接口

引入Smack依赖

  • org.igniterealtime.smack:smack-tcp 同时包含了Smack核心库。之所以有这个包,是因为XMPP也能运行在其他协议之上
  • org.igniterealtime.smack:smack-java7 平台依赖。用作初始化。不包含此库也能编译成功,但是跑不起来
  • org.igniterealtime.smack:smack-extensions Smake扩展包。算是必备,至少联系人管理功能需要这个包

Smack示例代码

package bj;

import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.junit.Test;
import org.jxmpp.jid.impl.JidCreate;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Set;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/11/22 下午4:33
 */
@Slf4j
public class BazTest {

    @Test
    public void testAlpha() throws IOException, InterruptedException, XMPPException, SmackException {
        // 创建连接,并连接到服务器
        AbstractXMPPConnection connection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder()
                .setUsernameAndPassword("gamma", "gamma")
                .setXmppDomain("172.16.5.254")
                .setHostAddress(InetAddress.getByName("172.16.5.254")) // 服务器地址直接用IP的话,不能用setHost()
                .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled) // 禁用安全模式,如果服务器不受信任
                .build()).connect();
        connection.login();

        // 监听XMPP包(包括PING、在线状态、聊天消息等)
        connection.addSyncStanzaListener(packet -> log.info("[SyncStanzaListener] Packet received {}", packet), stanza -> true);

        // 只监听聊天消息
        ChatManager.getInstanceFor(connection).addIncomingListener((entityBareJid, message, chat) -> {
            System.out.println(String.format("[IncomingListener] Message received %s : %s", entityBareJid, message.getBody()));
            // Echo此消息
            Try.run(() -> chat.send(message.getBody()));
            System.out.println(Roster.getInstanceFor(connection).getEntries());
        });

        // 发送消息
        connection.sendStanza(new Message("theta@172.16.5.254", "MESSAGE_BY_CONNECTION"));
        // 发送消息 方式二
        ChatManager.getInstanceFor(connection).chatWith(JidCreate.entityBareFrom("theta@172.16.5.254")).send("MESSAGE_BY_CHAT_MANAGER");

        // 获取联系人集合
        Thread.sleep(1000); // 等待联系人更新
        Set<RosterEntry> entries = Roster.getInstanceFor(connection).getEntries();
        log.info("Contacts: {} persons", entries.size());
        entries.forEach(System.out::println);

        // 保持运行
        Thread.currentThread().join();
    }
}

控制台日志

10:55:24.924 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received IQ Stanza (query jabber:iq:roster) [to=gamma@172.16.5.254/612m1g1ciz,id=gvsBl-5,type=result,]
10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/1gwvh0rdvv,id=L85kQ-6,type=available,]
10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/1pj92olp11,id=RamcN-7,type=available,]
10:55:24.933 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/8aadbwm30s,id=xkaYN-7,type=available,]
10:55:24.934 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/profanity,id=prof_presence_595,type=available,]
10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/9trigmn7f2,id=SJ41s-7,type=available,]
10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/42awvmq6te,id=iMJUx-6,type=available,]
10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/92ijqtzgxi,id=9gG6o-7,type=available,]
10:55:24.937 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/494vwn454w,id=byYRm-7,type=available,]
10:55:24.938 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/4wurqkoj8y,id=3BnGN-7,type=available,]
10:55:24.939 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Presence Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=gamma@172.16.5.254/9vx8ve5vdm,id=YSZxk-6,type=available,]
10:55:25.939 [main] INFO bj.BazTest - Contacts: 3 persons
: beta@172.16.5.254
: alpha@172.16.5.254
: theta@172.16.5.254
10:55:26.876 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Message Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=theta@172.16.5.254/profanity,id=prof_msg_670,type=chat,]
[IncomingListener] Message received theta@172.16.5.254 : hello
[: beta@172.16.5.254, : alpha@172.16.5.254, : theta@172.16.5.254]
10:55:28.839 [Smack Cached Executor] INFO bj.BazTest - [SyncStanzaListener] Packet received Message Stanza [to=gamma@172.16.5.254/612m1g1ciz,from=theta@172.16.5.254/profanity,id=prof_msg_671,type=chat,]
[IncomingListener] Message received theta@172.16.5.254 : world
[: beta@172.16.5.254, : alpha@172.16.5.254, : theta@172.16.5.254]

文章首发https://baijifeilong.github.io/2018/11/22/xmpp

XMPP大杂烩的更多相关文章

  1. 技术笔记:XMPP之openfire+spark+smack

    在即时通信这个领域目前只找到一个XMPP协议,在其协议基础上还是有许多成熟的产品,而且是开源的.所以还是想在这个领域多多了解一下. XMPP协议:具体的概念我就不写了,毕竟这东西网上到处是.简单的说就 ...

  2. xmpp

    xmpp学习 下载: Openfire 服务器:Openfire 4.0.2 客户端:Spark 2.7.7 安装 Openfire安装: 根据提示一直下一步,服务器域名设置为:localhost(p ...

  3. iOS XMPP 通信协议实现 图形化直观感受

    第一次随笔,实在不知写点什么有用的东西,那就分享一下本人最近的研究所得吧! 是关于iOS-XMPP-通信协议的实现,具体代码比较复杂,三言两句也实在难表达清楚,网上已有很多关于iOS XMPP协议的讲 ...

  4. (转)C# XMPP客户端与openfire通信(Matrix Xmpp 授权破解教程)

    FROM:http://www.cnblogs.com/crabo/p/CRACK_MATRIX_XMPP.html 如此著名的XMPP , 居然试过jabber-net, agsXmpp,matri ...

  5. XMPP iOS客户端实现三:登录、注册

    1.创建一个单例模式来管理xmpp的连接和操作 +(XMPPManager *)share { static XMPPManager *_share=nil; static dispatch_once ...

  6. XMPP iOS客户端实现二:xcode项目配置

    1.下载XMPPFramework,下载地址:https://github.com/robbiehanson/XMPPFramework 2.创建项目并将XMPP库引入: 3.添加需要的库文件: 4. ...

  7. Openfire/XMPP学习之——一个简单的Smack样例

    昨天讲了Openfire的搭建和配置,今天来讲一下Smack.如果对如何搭建和配置Openfire的,可以参考Openfire/XMPP学习之——Openfire的安装.配置. Smack是一个开源, ...

  8. MAC下的XMPP环境搭建

    实现即时通信有多种方式,下面讲的是Mac下使用XMPP来实现. XML Messages Presence Protocol 可扩展消息处理协议 简单讲就是基于XML语言的点对点即时通信协议  原理: ...

  9. XMPP开发环境配置

    首先配置XMPP开发环境配置需要的软件 先安装xampp-osx-1.8.3-5-installer.dmg 安装成功后launchpad里会多出一个XAMPP(其他),点开里面的manager-os ...

随机推荐

  1. Appium+Python自动化 2 定位元素方式

    1.找到 Android SDK安装路径tools 下面的 uiautomatorviewer.bat,如下截图 2.点击uiautomatorviewer.bat进行启动,左上角一共四个按钮,作用分 ...

  2. tensorflow学习之(十一)将python代码写入文件

    #save to file import tensorflow as tf import numpy as np ##(1)Save to file 把相关变量存储到文件中 #remember to ...

  3. 二叉树/DFS总结

    二叉搜索树(Binary Search Tree,又名排序二叉树,二叉查找树,通常简写为BST)定义如下: 空树或是具有下列性质的二叉树: ()若左子树不空,则左子树上所有节点值均小于或等于它的根节点 ...

  4. UC浏览器input文本框输入文字回车键自动提交

    这是测试今天在jira给我提出的一个bug 下面是贴的代码 屏蔽或者禁止回车键 <!DOCTYPE html> <html> <head> <meta cha ...

  5. 洛谷 p2440木材加工

    #include <iostream>#include <cstring>using namespace std;const int N = 1e5 + 100;int a[N ...

  6. 关于数据库连接时URL的问题

    最近在写一个简单的增删改查的代码时,遇到保存的中文都会变成问号(?),由于刚开始只是一些数据的保存,所以认为之后只要对数据库的编码进行修改即可,但是后来要对数据进行查找的时候发现根本查找不到, 当时用 ...

  7. BAT:文件中替换字符(保留空格和换行)

    @echo off rem CMD:"color --help" :: setting color:back white,content blue color f9 ::old s ...

  8. IDEA的Database表的基本操作

    1.创建表 方法一:直接创建:右键-new-table 方法2: 参考别的表,直接用语句,右键-DDL and Sources- 然后直接在控制台修改 修改后直接运行,表就建好了 2.备份表 先用上面 ...

  9. 了解AOP

    Spring AOP的实现是基于JAVA的代理机制, 从JDK1.3开始就支持代理功能, 但是性能成为一个很大问题, 为了解决JDK代理性能问题, 出现了CGLIB代理机制.它可以生成字节码, 所以它 ...

  10. Virtual Networking

    How the virtual networks used by guests work Networking using libvirt is generally fairly simple, an ...