使用Smack 4.2.3传输文件时频繁出现service-unavailable错误求助
解决Smack 4.2.3文件传输间歇性失败的问题
从你描述的情况和给出的IQ片段来看,这是基于XEP-0095(SI文件传输)的场景下出现的间歇性失败问题。结合Smack 4.2.3和ejabberd的环境,我整理了几个常见的排查和修复方向:
1. 补全Stream Initiation的Profile配置
你提供的IQ里profile='htt...明显是截断了,正常的文件传输profile应该是完整的http://jabber.org/protocol/si/profile/file-transfer。如果代码构建SI请求时没有完整指定这个值,或者解析时处理不完整,会导致服务器/客户端无法识别传输协议,直接引发失败。
- 修复示例:
SIBuilder siBuilder = new SIBuilder() .setMimeType("image/png") .setProfile("http://jabber.org/protocol/si/profile/file-transfer") .setId("jsi_8874207690796615693");
2. 检查ejabberd的文件传输相关模块配置
ejabberd默认可能没开启必要的文件传输支持模块,或者有资源限制:
- 确保
mod_proxy65(SOCKS5代理传输依赖)已启用,在ejabberd.yml中添加:
modules: mod_proxy65: {}
- 调整文件大小限制(按需修改):
mod_proxy65: max_size: 10485760 # 这里设置为10MB
3. 修正Smack异步回调的线程处理
Smack 4.x的多数操作是异步的,如果文件传输的回调逻辑阻塞了主线程,会导致请求超时或响应不及时:
- 建议用Smack的异步监听器处理SI请求,避免阻塞:
service.addAsyncStanzaListener(new StanzaListener() { @Override public void processStanza(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException { // 在这里处理SI请求的响应逻辑 } }, new StanzaTypeFilter(IQ.class));
4. 固定客户端JID的资源部分
从IQ的to和from字段能看到,客户端资源是随机长数字串,如果会话期间资源频繁变化,会导致XMPP路由错误:
- 连接时指定固定资源名,替代Smack自动生成的随机值:
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword("bob", "your_password") .setXmppDomain("domain") .setResource("desktop-client") // 自定义固定资源名 .build();
5. 捕获完整的错误IQ信息
你现在只拿到了请求片段,没有看到服务器返回的完整错误响应。建议添加错误监听器,捕获完整的错误XML,这能帮你精准定位问题:
service.addAsyncStanzaListener(new StanzaListener() { @Override public void processStanza(Stanza stanza) { IQ errorIq = (IQ) stanza; if (errorIq.getType() == IQ.Type.error) { Log.d("SMACK_FILE_TRANSFER_ERROR", errorIq.toXML().toString()); } } }, new StanzaTypeFilter(IQ.class) { @Override public boolean accept(Stanza stanza) { return super.accept(stanza) && ((IQ) stanza).getType() == IQ.Type.error; } });
先从捕获完整错误信息入手,这会让问题定位更高效,再结合上面的配置调整,应该能解决大部分间歇性失败的问题。
内容的提问来源于stack exchange,提问作者Muhammad Shuja
相关产品推荐
相关产品推荐

