You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Smack 4.2.4在jabb3r.org发送文件遇service-unavailable错误求助

解决Smack 4.2.4向jabb3r.org发送文件时的service-unavailable错误

首先,你遇到的XMPPError: service-unavailable - wait错误,核心原因是你强制启用了IBB(In-Band Bytestreams)传输方式,但jabb3r.org服务器并不支持IBB服务。而Xabber和Chat Secure能成功发送文件,是因为它们使用了**HTTP Upload(XEP-0363)**协议,也就是你看到的proxy.hot-chilli.net:5281/upload这个上传端点。

接下来我会给你具体的修复步骤和代码调整方案:

1. 关闭IBB强制设置

你的代码里设置了FileTransferNegotiator.IBB_ONLY = true;,这会让Smack只尝试用IBB传输,直接忽略其他更合适的方式(比如HTTP Upload)。先把这行代码删掉,让Smack自动协商最优的传输机制。

2. 改用HTTP Upload实现文件发送

Smack 4.2.4已经支持XEP-0363 HTTP Upload,你需要使用HttpUploadManager来处理文件上传,而不是原来的FileTransferManager。以下是调整后的代码:

public void send(String id, String path) throws XmppStringprepException {
    // 初始化服务发现管理器,确保支持HTTP Upload特性
    ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
    if (sdm == null) {
        sdm = new ServiceDiscoveryManager(connection);
    }
    sdm.addFeature("urn:xmpp:http:upload:0"); // HTTP Upload的特性标识

    // 获取HTTP Upload管理器
    HttpUploadManager uploadManager = HttpUploadManager.getInstanceFor(connection);
    File file = new File(path);

    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            try {
                // 向服务器请求上传插槽(slot)
                HttpUploadSlot slot = uploadManager.requestUploadSlot(
                        JidCreate.entityBareFrom("fattaneh123@jabb3r.org"),
                        file.getName(),
                        file.length(),
                        "application/octet-stream" // 根据文件类型调整MIME类型
                );

                // 使用HTTP PUT将文件上传到指定的URL
                OkHttpClient client = new OkHttpClient();
                RequestBody requestBody = RequestBody.create(file, MediaType.parse("application/octet-stream"));
                Request request = new Request.Builder()
                        .url(slot.getPutUrl())
                        .put(requestBody)
                        .build();
                Response response = client.newCall(request).execute();

                if (response.isSuccessful()) {
                    // 上传成功后,通过XMPP消息发送下载URL给对方
                    Message message = new Message(JidCreate.entityBareFrom("fattaneh123@jabb3r.org"));
                    message.setBody("我发送了一个文件: " + slot.getGetUrl());
                    // 也可以使用XEP-0065的文件传输提示,或者自定义的消息扩展
                    connection.sendStanza(message);
                    return "文件上传并发送成功";
                } else {
                    return "文件上传失败: " + response.message();
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "发生错误: " + e.getMessage();
            }
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i("file transfer", result);
        }
    }.execute();
}

3. 注意事项

  • 确保你的项目依赖了OkHttp(或者其他HTTP客户端),因为Smack的HttpUploadManager只负责获取上传插槽,实际的文件上传需要你自己实现HTTP请求。
  • 根据你发送的文件类型调整MIME类型(比如图片用image/jpeg,文档用application/pdf等),这样接收端能正确识别文件类型。
  • 接收端需要支持HTTP Upload协议才能直接从下载URL获取文件,这也是Xabber和Chat Secure能正常接收的原因。

为什么原来的FileTransferManager不行?

传统的FileTransferManager主要用于XEP-0065(SOCKS5 Bytestreams)和XEP-0047(IBB),但很多现代XMPP服务器更倾向于支持HTTP Upload,因为它更高效,不需要额外的端口转发,对移动端更友好。jabb3r.org显然是优先支持HTTP Upload,所以你需要切换到这个协议。

内容的提问来源于stack exchange,提问作者ali mardani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:11