如何使用XMPP协议正确连接Strophe.js客户端和Prosody服务器

3

我已经安装并配置了Prosody服务器。它监听标准的localhost:5222端口。在配置文件中添加了管理员用户1@example.com。但是每次向服务器发送请求都会出现错误:

<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" id="" version="1.0">
    <stream:error>
        <not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/>
    </stream:error>
</stream:stream>

作为客户端,我想使用strophe.js。我只发送出席状态 ($pres)。以下是我的代码。
'use strict';

angular.module('xmppTestApp')
    .controller('ChatCtrl', function () {

    var vm = this;

    var url = "http://localhost:5222";
    var connection = null; 

    var output = document.getElementById("output");

    function log(message) {
        var line = document.createElement("div");
        line.textContent = message;
        output.appendChild(line);
    }

    function connectHandler(cond) {
        if (cond == Strophe.Status.CONNECTED) {
            log("connected");
            connection.send($pres());
        }
        else {
            log("not connected");
        }
    }

    vm.connectB = function() {
        var username = document.getElementById("username").value;
        var password = document.getElementById("password").value;

        console.info(url);
        console.info(username);
        console.info(password);

        connection = new Strophe.Connection(url);
        connection.connect(username, password, connectHandler);
    }
});

在控制台中我看到了错误:

XMLHttpRequest cannot load http://localhost:5222/. No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:9000' is therefore not allowed access.

我该如何在请求中添加'Access-Control-Allow-Origin'头部信息?

当我尝试发送请求到 localhost:5222(不带http)时,我得到以下错误:

XMLHttpRequest cannot load localhost:5222. Cross origin requests are only supported for HTTP.

当我通过 WebSocket 发送它时,我收到的是:
WebSocket connection to 'ws://localhost:5222/' failed: Error during WebSocket handshake: Unexpected response code: 200 

Fiddler为我提供了协议违规报告:

The server didn't return properly-formatted HTTP Headers. Maybe missing altogether 
(e.g. HTTP/0.9), maybe only \r\r instead of \r\n\r\n?
1个回答

6
首先,看起来你正在尝试直接连接到5222端口(通常用于XMPP),但是为了从客户端网页使用Strophe,你必须使用HTTP-Binding(又称BOSH)。
XMPP与BOSH的区别
Strophe“讲”XMPP,但它独特的地方在于它实际上不使用XMPP协议传输数据,而是依靠BOSH(即同步HTTP双向流)。这是因为XMPP协议旨在始终保持客户端和服务器连接,我们都知道这不是HTTP的工作方式。简单来说,BOSH允许您的HTTP客户端异步接收数据,而无需显式请求。如果您有关于BOSH的更多问题,请告诉我,我会尽力解释它的作用以及为什么需要它。
在使用Strophe之前,你必须在prosody中启用此功能,请查看此链接以进行设置。 Prosody Docs - Setting up BOSH 一旦您设置了BOSH,您需要更改客户端代码以使用不同的地址。 您可能已经将BOSH的路径+端口设置为:5280 / http-bind / 之类的内容。 在这一点上,您需要确保Strophe使用此URL而不是实际的XMPP端口5222。
最后,对于网站域和端口之外的任何资源,都需要CORS。 在您的示例中,您的客户端必须向在与页面本身(Strophe和Prosody之间的连接)不同的端口+域上运行的URL发出请求。 好消息是,Prosody已经支持CORS,并且启用它非常简单。 所有这些都在我之前链接的页面上有更详细的解释。
希望这有所帮助!

在更改配置后,我建议尝试重新启动prosody,您可以通过浏览到“localhost:5280/crossdomain.xml”轻松测试CORS是否已启用。如果找不到此文件,则CORS尚未启用。另外,请确保cross-domain-bosh = true位于配置的全局部分中。此外,请尝试在/http-bind之后添加一个反斜杠,例如:/http-bind/ - fpsColton
关于用户注册,一旦您配置了服务器以允许注册,其余的工作就由客户端代码来完成。注册用户的过程在XEP-077中有详细说明(http://xmpp.org/extensions/xep-0077.html)。一旦您开始使用Strophe,XEP文档将成为您宝贵的资源。用户注册的过程太复杂了,无法在评论中解释清楚,如果还没有被问到,这值得提出一个单独的问题! - fpsColton
crossdomain.xml应该由Prosody为您生成。我个人从未使用过Prosody,所以不确定为什么它无法正常工作。您是否尝试过重新启动所有相关的Prosody服务? - fpsColton
谢谢你的帮助。 - magos
Prosody pre 0.10存在一个bug,由于某些错误条件下头部信息不完整,会返回跨域问题。因此,基本上可能认为存在跨域问题,但实际上却是其他错误,并且Prosody服务器提前退出,试图发送错误消息,但没有发送完整的头部信息,因此会收到CORS错误。0.10+版本解决了这个问题。 - Tony
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接