Ubuntu 22.04 安装 Apache Vysper 指南

Ubuntu 22.04 从零安装 Apache Vysper 0.7 完整指南:Temurin JDK 8 部署、官方归档下载校验、账号初始化、端口验证与 XMPP 注册登录发消息闭环实测

Apache VysperApache VysperXMPPJavaUbuntuUbuntu 22.042026/10/16

Ubuntu 22.04 安装 Apache Vysper 指南

目标:在一台全新的 Ubuntu 22.04 服务器上,从零安装并跑通 Apache Vysper 0.7 XMPP 服务器——包括 JDK 准备、官方源下载校验、账号初始化、服务启动,最后用客户端完成「注册 → 登录 → 互发消息」的最小闭环验证。每一步都给出真实命令与回显。

一、版本核实与安装选型

动手之前先把版本问题说透。Vysper 的最后一个正式版本是 0.7(2011 年 10 月发布),此后 Apache 官方再未发布新版本,Maven Central 上的构件也停留在 0.7。这不是「旧版」,而是「唯一版」。

1)官方归档核实(archive.apache.org 永久归档):

curl -s https://archive.apache.org/dist/mina/vysper/ | grep -oE 'vysper="[0-9.]+/'

实测输出:

vysper="0.5/
vysper="0.6/
vysper="0.7/
curl -s https://archive.apache.org/dist/mina/vysper/0.7/ | grep -oE '<a href="[^"]+"'

实测输出:

<a href="vysper-0.7-bin.tar.gz">
<a href="vysper-0.7-bin.tar.gz.md5">
<a href="vysper-0.7-src.tar.gz">
<a href="vysper-0.7-src.zip">

2)Maven Central 核实(org.apache.vysper:vysper 坐标下有同样的二进制包):

curl -s https://repo1.maven.org/maven2/org/apache/vysper/vysper/0.7/ | grep -oE '<a href="[^"]+"' | head -4

实测输出:

<a href="../">
<a href="vysper-0.7-bin.tar.gz">
<a href="vysper-0.7-bin.tar.gz.md5">
<a href="vysper-0.7-bin.tar.gz.sha1">
事实结论
归档与 Maven Central 均只有 0.7没有可选的"新版",本文安装 0.7
0.7 是 2011 年代码(Spring 2.x、MINA 2.0.x 时代)对 JDK 有约束,见第三节
无 apt/rpm 包,只有 tar.gz安装方式 = 下载解压 + 脚本启动

💡 技术拓展:archive.apache.org 是 ASF 的官方永久归档,历史上所有发行版本都在这里保留;Maven Central 的 org.apache.vysper:vysper 构件与归档文件相同(均 17,610,698 字节),两者任选其一即可,本文主线用官方归档。

二、环境说明与前置条件

本文全部操作在一台 Ubuntu 22.04 服务器(x86_64)上完成,软件均安装到 /opt 目录,工作演示目录为 /root。

head -2 /etc/os-release && uname -m

实测输出:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
x86_64

确认基础工具(curl/wget/openssl/python3 都是验证下载完整性与跑通闭环要用的):

which curl wget openssl python3

实测输出:

/usr/bin/curl
/usr/bin/wget
/usr/bin/openssl
/usr/bin/python3

缺哪个就 apt-get install -y curl ca-certificates 补上(curl 7.81.0 实测足够)。

两个前置说明:

  1. 网络:本文实验环境通过 HTTP 代理出网,下载命令里的 -x http://192.168.1.62:7897 是代理参数,普通网络环境删去即可,其余完全一致。
  2. 先卸载预装 Java:java -version 若显示 OpenJDK 11/17 等新版本,不要直接拿来跑 Vysper——0.7 依赖的 Spring 2.x 老字节码在 JDK 9+ 模块化体系下会启动失败,下一节用 tarball 装老 JDK 就是为了绕开这个坑。

三、安装 Temurin JDK 8

Vysper 0.7 的 Java 生态是 2011 年的,经实测验证的可用组合是 Temurin JDK 8(1.8.0_504-b01)。下载走 adoptium 官方 API(会 307 重定向到 GitHub Releases):

mkdir -p /opt/jdk /root/dl
cd /root/dl
curl -sIL -x http://192.168.1.62:7897 "https://api.adoptium.net/v3/binary/latest/8/ga/linux/x64/jdk/hotspot/normal/eclipse" | grep -iE "^HTTP|^location" | head -6

实测输出:

HTTP/1.1 200 Connection established
HTTP/2 307 
location: https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u504-b01/OpenJDK8U-jdk_x64_linux_hotspot_8u504b01.tar.gz

真实下载(103MB):

curl -s -x http://192.168.1.62:7897 -L -o temurin8-jdk.tar.gz "https://api.adoptium.net/v3/binary/latest/8/ga/linux/x64/jdk/hotspot/normal/eclipse"
ls -l temurin8-jdk.tar.gz
-rw-r--r-- 1 root root 103542511 Oct 16 07:01 temurin8-jdk.tar.gz

解压到 /opt/jdk 并验证版本:

tar xzf temurin8-jdk.tar.gz -C /opt/jdk/
/opt/jdk/jdk8u504-b01/bin/java -version
openjdk version "1.8.0_504"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_504-b01)
OpenJDK 64-Bit Server VM (Temurin)(build 25.504-b01, mixed mode)

💡 技术拓展:为什么不用 apt install openjdk-8-jdk?Ubuntu 22.04 官方源的 OpenJDK 8 构建较旧且随发行版更新不受控,adoptium(原 AdoptOpenJDK)的 Temurin 构建是社区长期维护的 JDK 8 发行版,tarball 方式安装路径固定(/opt/jdk/jdk8u504-b01)、升级可控,也便于在第八节做多 JDK 对比。

四、下载并解压 Vysper 0.7

4.1 方案 A:官方归档下载(主线)

cd /root/dl
curl -s -x http://192.168.1.62:7897 -O https://archive.apache.org/dist/mina/vysper/0.7/vysper-0.7-bin.tar.gz
curl -s -x http://192.168.1.62:7897 -O https://archive.apache.org/dist/mina/vysper/0.7/vysper-0.7-bin.tar.gz.md5
ls -l vysper-0.7-bin.tar.gz
-rw-r--r-- 1 root root 17610698 Oct 16 07:01 vysper-0.7-bin.tar.gz

完整性校验有个坑:归档附带的 .md5 文件是"裸哈希"(只有 32 位摘要、没有文件名),直接 md5sum -c 会报错:

md5sum: vysper-0.7-bin.tar.gz.md5: no properly formatted MD5 checksum lines found

正确做法是自己拼接校验行或直接对比:

cat vysper-0.7-bin.tar.gz.md5; echo
md5sum vysper-0.7-bin.tar.gz

实测输出(一致):

5d39a931c94bf46e259d8bb0a4ce385b
5d39a931c94bf46e259d8bb0a4ce385b  vysper-0.7-bin.tar.gz

解压到 /opt/vysper:

tar xzf vysper-0.7-bin.tar.gz -C /opt/vysper/
ls /opt/vysper/vysper-0.7/
ABOUT.txt
ARCHITECTURE.txt
LICENSE.txt
NOTICE.txt
bin
config
lib
log

💡 技术拓展:解压时 tar 会打印一行 tar: A lone zero block at 37958 警告——这是 2011 年打包工具留下的非标准结尾填充块,不影响解压结果(解压出的文件清单与内容完整),无需处理。

4.2 方案 B:Maven Central 下载(备选)

网络只通 Maven 仓库时,用坐标 org.apache.vysper:vysper:0.7 直取同一文件:

curl -s -O https://repo1.maven.org/maven2/org/apache/vysper/vysper/0.7/vysper-0.7-bin.tar.gz

后续步骤与方案 A 完全一致。两个源文件 MD5 相同,可互换。

五、首次配置

5.1 预置账号

默认配置里预置了 admin@vysper.org,密码占位为 CHOOSE A SECURE PASSWORD。修改 config/spring-config.xml 中的账号表:把 admin 口令改掉,并新增 user1、user2 两个测试账号:

cd /opt/vysper/vysper-0.7
cp config/spring-config.xml config/spring-config.xml.orig
sed -i 's|<entry key="admin@vysper.org" value="CHOOSE A SECURE PASSWORD" />|<entry key="admin@vysper.org" value="q1w2e3r4" />\n                <entry key="user1@vysper.org" value="q1w2e3r4" />\n                <entry key="user2@vysper.org" value="q1w2e3r4" />|' config/spring-config.xml
sed -n '35,44p' config/spring-config.xml

实测输出:

    <bean id="addUsers" class="org.apache.vysper.spring.AddUserHelper">
        <constructor-arg index="0">
            <map>
                <entry key="admin@vysper.org" value="q1w2e3r4" />
                <entry key="user1@vysper.org" value="q1w2e3r4" />
                <entry key="user2@vysper.org" value="q1w2e3r4" />
                <!--<entry key="user1@vysper.org" value="CHOOSE A SECURE PASSWORD" />-->
                <!--<entry key="user2@vysper.org" value="CHOOSE A SECURE PASSWORD" />-->

注意:默认存储是纯内存实现,重启后这些账号会按配置重建;若改用持久存储后不再需要固定演示账号,可整段删除 addUsers Bean(存储选项详解见《Apache Vysper 配置参数详解》)。

5.2 JVM 参数

bin/ 下创建 setenv.sh(默认没有,run.sh 启动时会自动 source 它):

cat > bin/setenv.sh <<'EOF'
export JAVA_HOME=/opt/jdk/jdk8u504-b01
export JAVA_OPTS="-Xms256m -Xmx256m"
EOF
chmod +x bin/setenv.sh
cat bin/setenv.sh
export JAVA_HOME=/opt/jdk/jdk8u504-b01
export JAVA_OPTS="-Xms256m -Xmx256m"

💡 技术拓展:网上老资料常见 -XX:PermSize=64m -XX:MaxPermSize=256m 写法,那是 JDK 7 持久代参数,JDK 8 已移除(启动时打 support was removed in 8.0 警告并被忽略),照抄无害但别再抄。

六、启动服务与端口验证

前台/后台启动都是 bin/run.sh,生产用 nohup 甩后台:

cd /opt/vysper/vysper-0.7
nohup bin/run.sh > /root/vysper-opt.log 2>&1 &
sleep 12
ps -ef | grep [S]erverMain | cut -c1-130
ss -tlnp | grep 5222

实测输出:

root       4018   1  0 07:05 ?        00:00:05 /opt/jdk/jdk8u504-b01/bin/java -Xms256m -Xmx256m -classpath :/opt/vysper/vysper-0.7/conf ...
LISTEN 0      50                 *:5222            *:*    users:(("java",pid=4018,fd=107))

5222(XMPP 客户端连接端口)进入监听即启动成功。日志在安装目录 log/ 下:

ls -l log/
-rw-r--r-- 1 root root    0 Oct 16 07:05 stanza.log
-rw-r--r-- 1 root root  1383 Oct 16 07:05 vysper_server.log

stanza.log 记录收发的每一条 XMPP 报文,vysper_server.log 记录服务器运行日志。JVM 参数可用 jps 复核:

/opt/jdk/jdk8u504-b01/bin/jps -v | grep ServerMain
4018 ServerMain -Xms256m -Xmx256m -Dapp.name=run.sh -Dapp.pid=4018 -Dapp.repo=/opt/vysper/vysper-0.7/lib -Dbasedir=/opt/vysper/vysper-0.7

停止服务用 kill $(ps -ef | awk '/[S]erverMain/{print $2}')(详见《Apache Vysper 常用 CLI 命令与工具详解》)。

七、闭环验证:注册 → 登录 → 发消息

光看端口监听不算数,用真实 XMPP 客户端把链路走通。Vysper 0.7 自带证书太老(2005 年 511 位 MD5 证书),python 标准库连接时必须显式指定 TLS 1.2(原因见第十节 FAQ-4)。

7.1 客户端脚本

保存为 /root/xmpp_client.py(标准库实现,无需 pip):

#!/usr/bin/env python3
# Vysper 0.7 闭环测试:STARTTLS(TLS1.2) -> SASL PLAIN -> bind -> session -> 双向消息
import socket, ssl, base64, re

HOST, PORT, DOMAIN = '127.0.0.1', 5222, 'vysper.org'

def b64(s):
    return base64.b64encode(s.encode()).decode()

class C:
    def __init__(self, name, user, pwd):
        self.name, self.user, self.pwd = name, user, pwd
        self.tcp = socket.create_connection((HOST, PORT), 10)

    def send(self, d):
        print(f">>> [{self.name}] {d}")
        self.tcp.sendall(d.encode())

    def recv(self, t=6):
        self.tcp.settimeout(t)
        buf = b''
        try:
            while True:
                c = self.tcp.recv(65536)
                if not c: break
                buf += c
                if any(x in buf for x in [b'</iq>', b'</success>', b'</failure>',
                                          b'</proceed>', b'</message>']):
                    break
        except socket.timeout:
            pass
        out = buf.decode(errors='replace')
        if out:
            print(f"<<< [{self.name}] {out[:220]}")
        return out

    def login(self, res):
        # 1) 明文流 -> 流特性(含 starttls required)
        self.send(f"<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
                  f"xmlns='jabber:client' to='{DOMAIN}' version='1.0'>")
        f = self.recv()
        assert 'starttls' in f, 'server did not offer STARTTLS: ' + f
        # 2) STARTTLS -> TLS1.2
        self.send("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
        self.recv()
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)   # 0.7 老证书必须锁 TLS1.2
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE              # 自签证书,跳过校验
        self.tcp = ctx.wrap_socket(self.tcp)
        print(f"--- [{self.name}] TLS established: {self.tcp.version()}")
        # 3) 加密流 -> SASL PLAIN
        self.send(f"<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
                  f"xmlns='jabber:client' to='{DOMAIN}' version='1.0'>")
        self.recv()
        self.send(f"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"
                  f"{b64(chr(0)+self.user+chr(0)+self.pwd)}</auth>")
        r = self.recv()
        assert '<success' in r, f'SASL failed: {r}'
        # 4) bind + session
        self.send(f"<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
                  f"xmlns='jabber:client' to='{DOMAIN}' version='1.0'>")
        self.recv()
        self.send(f"<iq type='set' id='b1'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
                  f"<resource>{res}</resource></bind></iq>")
        r = self.recv()
        self.full_jid = re.search(r'<jid>([^<]+)</jid>', r).group(1)
        self.send(f"<iq type='set' id='s1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>")
        self.recv()
        print(f"=== [{self.name}] login OK, full jid = {self.full_jid}")

u1 = C('user1', 'user1', 'q1w2e3r4')
u1.login('c1')
u2 = C('user2', 'user2', 'q1w2e3r4')
u2.login('c2')

print("\n########## user1 -> user2 ##########")
u1.send("<message to='user2@vysper.org' type='chat'><body>hello from user1</body></message>")
m = u2.recv()
assert 'user1@vysper.org' in m and 'hello from user1' in m, 'delivery failed: ' + m

print("\n########## user2 -> user1 ##########")
u2.send("<message to='user1@vysper.org' type='chat'><body>reply from user2</body></message>")
m = u1.recv()
assert 'user2@vysper.org' in m and 'reply from user2' in m, 'delivery failed: ' + m

print("\nALL MESSAGE EXCHANGE OK")

7.2 登录与互发消息

cd /root && timeout 60 python3 xmpp_client.py

实测输出(节选):

--- [user1] TLS established: TLSv1.2
=== [user1] login OK, full jid = user1@vysper.org/542917d76a1a4cf58594618854f0dc33
--- [user2] TLS established: TLSv1.2
=== [user2] login OK, full jid = user2@vysper.org/e02133e1779e42178f85b984cb527c68

########## user1 -> user2 ##########
<<< [user2] <message xmlns="jabber:client" to="user2@vysper.org" type="chat" from="user1@vysper.org/c1"><body>hello from user1</body></message>

########## user2 -> user1 ##########
<<< [user1] <message xmlns="jabber:client" to="user1@vysper.org" type="chat" from="user2@vysper.org/c2"><body>reply from user2</body></message>

ALL MESSAGE EXCHANGE OK

TLS 加密、SASL 认证、资源绑定、双向投递全部通过。

7.3 动态注册新账号(XEP-0133)

预置账号之外,Vysper 支持 XEP-0133 服务管理命令在线加用户(admin 已在 ServiceAdministrationModule 的 addAdmins 列表里)。流程是 ad-hoc 命令三步走:execute 拿表单 → submit 提交 → completed 确认:

cd /root && timeout 90 python3 xep0133.py 2>/dev/null | grep -E '^==='

实测输出:

=== [admin] login OK, full jid = admin@vysper.org/ab4d06d942f54d58af2ea12c8a03a391
=== [user3] login OK, full jid = user3@vysper.org/eec5b0f44cea42df9ec3af0433b0e967
=== user3 LOGIN OK -> XEP-0133 add-user 生效

表单提交的关键报文与服务器确认(脚本完整版见《Apache Vysper 常用 CLI 命令与工具详解》):

>>> [admin] <iq type='set' id='ex2' from='admin@vysper.org/adminres' to='vysper.org'><command xmlns='http://jabber.org/protocol/commands' node='http://jabber.org/protocol/admin#add-user' sessionid='455a2804092f48ddabfab857743358e1' action='complete'><x xmlns='jabber:x:data' type='submit'>...</x></command></iq>
<<< [admin] <iq xmlns="jabber:client" to="admin@vysper.org/ab4d06d942f54d58af2ea12c8a03a391" type="result" id="ex2"><command xmlns="http://jabber.org/protocol/commands" node="http://jabber.org/protocol/admin#add-user" sessionid="455a2804092f48ddabfab857743358e1" status="completed"></command></iq>

新注册的 user3 立即可用,与 user1 互发消息:

cd /root && timeout 90 python3 b1_user3_msg.py 2>/dev/null | grep -E "^===|ALL"

实测输出:

--- [user1] TLS established: TLSv1.2
=== [user1] login OK, full jid = user1@vysper.org/e9ef71e921a34cb2952355f339e6d0bf
--- [user3] TLS established: TLSv1.2
=== [user3] login OK, full jid = user3@vysper.org/3ba68bde4b33481c945f8b91c0675b6b
=== USER3->USER1 MESSAGE OK (XEP-0133 registered account works)

至此「静态预置 + 动态注册 → 登录 → 互发消息」闭环全部走通。若还想开放用户自助注册(XEP-0077 带内注册模块),在 spring-config.xml 的 modules 列表追加一行 Bean 即可,实测步骤见《Apache Vysper 配置参数详解》2.6 节。

八、进阶:JDK 7 组合实测与兼容性结论

老系统迁移常问:能不能用更老的 JDK 7?实测回答。装 Zulu JDK 7(Azul 官方分发,zulu7.56.0.11-ca-jdk7.0.352):

ls -d /opt/jdk/zulu7*
/opt/jdk/zulu7.56.0.11-ca-jdk7.0.352-linux_x64

把 bin/setenv.sh 的 JAVA_HOME 换成 Zulu 7 路径重启,服务本身可以起来(5222 正常监听,进程确认是 JDK7):

ps -ef | grep [S]erverMain | grep -oE "/opt/jdk/[^/]+/bin/java"
ss -tlnp | grep 5222
/opt/jdk/zulu7.56.0.11-ca-jdk7.0.352-linux_x64/bin/java
LISTEN 0      50                 *:5222            *:*    users:(("java",pid=5492,fd=107))

但配合自带老证书时任何客户端都无法完成 TLS 握手——JDK 7u352 自身的算法约束直接拒绝 511 位 MD5 证书,握手被服务端终止:

  • Java 客户端(JDK 8 运行):
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Certificates do not conform to algorithm constraints
  • python 降级到 TLSv1 并放宽 OpenSSL 安全级别(SECLEVEL=0)也失败:
FAILED: SSLEOFError [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1007)

换上 2048 位新证书后再测,JDK 7 完全可用(换证步骤见《Apache Vysper 配置参数详解》第六节):

=== [user2] login OK
ALL OK: legacy-TLS login + message exchange verified        # Java 客户端
--- TLS established: TLSv1.2
ALL MESSAGE EXCHANGE OK                                     # python 客户端
组合启动登录+消息结论
Temurin JDK 8 + 内置证书✅✅(客户端需强制 TLS 1.2)推荐
Temurin JDK 8 + 新 2048 证书✅✅(TLS 1.2/1.3 均可)生产推荐
Zulu JDK 7u352 + 内置证书✅❌ 服务端拒绝握手不可用
Zulu JDK 7u352 + 新 2048 证书✅✅可用,仅老系统迁移时选

验证完把 setenv.sh 的 JAVA_HOME 换回 JDK 8 并重启即可。

九、systemd 托管(可选)

生产服务器建议交给 systemd 管理(开机自启、崩溃拉起)。/etc/systemd/system/vysper.service:

[Unit]
Description=Apache Vysper XMPP Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/vysper/vysper-0.7
Environment=JAVA_HOME=/opt/jdk/jdk8u504-b01
ExecStart=/opt/vysper/vysper-0.7/bin/run.sh
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

两点强调:WorkingDirectory 必须指向安装目录——run.sh 的 classpath、log4j 的 log/ 相对路径、JCR 存储的 repository/ 位置都依赖它;JAVA_OPTS 想自定义时在 [Service] 段加 Environment=JAVA_OPTS="-Xms256m -Xmx256m" 即可被 setenv.sh 的 export 覆盖,反之亦然,以 exec 展开时的最后一个为准。

⚠️ 本文实验环境为最小化系统(无 systemd/1 号进程),上述 unit 文件按 systemd 规范编写,未在实验机上执行 systemctl 实测,读者上真机后请先 systemd-analyze verify vysper.service 校验再启用。

十、升级、多实例与卸载

升级/换版本:Vysper 只有 0.7 一个版本,不存在升级路径;若未来官方出新版,保留 config/ 与 log/ 两个目录、替换其余目录即可(新旧版本配置格式无兼容承诺,先备份 spring-config.xml)。

多实例:再复制一份安装目录(如 /opt/vysper/vysper-0.7-2),修改 2.1 节 tcpEndpoint 端口避开 5222,各自 nohup 启动。注意确认进程归属:ps -ef | grep ServerMain,两实例的 -Dbasedir= 不同。

卸载:Vysper 不写系统目录,卸载即删目录 + 停进程:

kill $(ps -ef | awk '/[S]erverMain/{print $2}')
rm -rf /opt/vysper /opt/jdk /root/dl

十一、常见问题

1. md5sum -c 报 no properly formatted MD5 checksum lines found? 归档的 .md5 是裸哈希,直接对比(见 4.1)或自己拼 "<hash> 文件名" > check.md5 再 -c。

2. tar 解压报 A lone zero block? 2011 年打包的历史遗留,警告无害,解压结果完整(4.1 节已验证文件清单)。

3. 启动后 5222 不监听、进程却不退出? 端口被占。Vysper 的 MINA 绑定失败只抛异常不退出,先杀干净旧实例再启动。日志特征:

Caused by: org.apache.mina.core.RuntimeIoException: Failed to bind

4. python 报 SSLEOFError 连不上? 两个原因叠加:内置 2005 年证书太老 + 新版 OpenSSL 默认安全级别高。python 客户端必须用 ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) 锁定 TLS 1.2(TLS 1.3 握手会因证书签名算法被拒);根治方案是换 2048 位证书(见《Apache Vysper 配置参数详解》第六节,换完后 TLS 1.3 也能协商成功)。

5. 启动日志有 PermSize warning? 老配置模板抄来的 JDK 7 参数,JDK 8 已忽略并移除持久代,删掉即可(见 5.2 节)。

6. 端口 5222 能通但客户端卡在流头? 确认 to= 属性与 spring-config.xml 的域名一致(默认 vysper.org),域名不匹配时服务器不返回流特性。改域名的方法与联动项见《Apache Vysper 配置参数详解》2.5 节。


至此一台能注册、登录、收发消息的 Vysper 0.7 就装好了。下一步:调参见《Apache Vysper 配置参数详解》,命令行运维见《Apache Vysper 常用 CLI 命令与工具详解》,产品定位与替代方案对比见《Apache Vysper 介绍与选型指南》。