【问题标题】:Strophe.js not reconnecting after disconnect断开连接后 Strophe.js 未重新连接
【发布时间】:2019-02-22 10:48:48
【问题描述】:

我正在从事一个项目,该项目在 wordpress 后端(用于存储消息、帖子)、用于用户交互的 Angular 前端 (Angluar 6x) 和用于从 Web 应用程序内进行聊天通信的 eJabber 服务器之间进行复杂交互。
为了实现这一点,我正在尝试将 strophe.js 集成到 Angular 框架中。
我使用的身份验证方法很复杂。当一个新用户通过合适的(角度)表单注册到 wordpress 后端时,我已经设置了钩子,这些钩子也自动将新用户订阅到我的本地 eJabberd 服务器。为了管理身份验证,为了避免最终用户输入两次他/她的凭据,我在 eJabberd 中设置了一个自定义 extauth 脚本(基于this),它与自定义 wordpress rest API 端点并行工作(I'我为此使用 JWT)。
extauth 脚本运行良好,我可以使用各种聊天客户端(Adium、Apple 的消息等)成功连接到本地 eJabberd 服务器。 我也可以从我的网络应用程序中连接(如前所述,使用 strophe)到 eJabber。

这是我用来管理连接的代码的 sn-p (ChatPanel.Service.ts):

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Strophe, $pres } from 'strophe.js';

import { EJABBERD } from 'app/api/api.module';

var chatPanelServiceInstance: any = null;

@Injectable()
export class ChatPanelService
{
    contacts: any[];
    chats: any[];
    user: any;
    client: any;

    // Private
    private _xmppConnectionsString: String = "ws://" + EJABBERD.host + ":5280/ws";
    private _xmppConnection: any = null;

    /**
     * Constructor
     */
    constructor(
    )
    {
        chatPanelServiceInstance = this;
        Strophe.log = (level: any, msg: string) => { console.log(level + ": " + msg); };
    }

    /**
     * Log into eJabberd
     *
     * @param {string} jid      user name
     * @param {string} password password (actually, the user token)
     */
    login(jid: string, password: string): void
    {
        if ( ! this._xmppConnection ) {
            this._xmppConnection = new Strophe.Connection( this._xmppConnectionsString , {'keepalive': true});
        }

        this._xmppConnection.connect(jid+'@'+EJABBERD.host, password, this._onConnect);
    }

    /**
     * Disconnect from eJabberd
     */
    logOut(): void
    {
        if ( this._xmppConnection ) {
            this._xmppConnection.options.sync = true;
            this._xmppConnection.flush();
            this._xmppConnection.disconnect("logout");
            this._xmppConnection = null;
        }
    }

    /**
     * eJabberd XMPP message Handler
     * @param {string} msg Message received
     */
    private _onMessage(msg: string): boolean
    {
        console.log("eJabber Msg: " + msg);

        return true;
    }

    /**
     * eJabberd connection Handler
     * @param {any} status connection result
     */
    private _onConnect(status: any): void
    {
        switch (status) {
            case Strophe.Status.CONNECTING:
                console.log("Connecting to eJabberd...");
                break;
            case Strophe.Status.CONNFAIL:
                console.log("eJabberd connection failed!");
                break;
            case Strophe.Status.DISCONNECTING:
                console.log("Disconnecting from eJabberd...");
                break;
            case Strophe.Status.DISCONNECTED:
                console.log("Disconnected from eJabberd");
                break;
            case Strophe.Status.CONNECTED:
                //handler function  [ onMessage() ]  will be called when the user recieves a new message
                chatPanelServiceInstance._xmppConnection.addHandler(chatPanelServiceInstance._onMessage, null, 'message');

                //Setting our presence in the server. so that everyone can know that we are online
                chatPanelServiceInstance._xmppConnection.send($pres().tree());

                console.log("eJabberd connected!");
                break;
            case Strophe.Status.AUTHENTICATING:
                console.log("eJabberd authenticating...");
                break;
            case Strophe.Status.AUTHFAIL:
                console.log("eJabberd authentication failed!");
                break;
            case Strophe.Status.ERROR:
                console.log("eJabberd generic connection error!");
                break;
            case Strophe.Status.ATTACHED:
                console.log("eJabberd connection attached!");
                break;
            case Strophe.Status.REDIRECT:
                console.log("eJabberd connection redirected!");
                break;
            case Strophe.Status.CONNTIMEOUT:
                console.log("eJabberd connection timeout!");
                break;
            default:
                console.log("eJabberd: Unknow connection status");
        }
    }

当我在注销后尝试重新连接到服务器时出现问题。

当我从我的 Web 应用程序中注销时(即调用我的 chatpanel.service 中的 logout()),如果我尝试再次登录,我不会收到来自 ejabber 服务器的响应。显然,服务器停止侦听来自 strophe 的任何进一步请求。
我已经尝试过使用 websockets 和 BOSH。最后的结果是一样的。

这是浏览器控制台的快照:

First, successfull, login (WebSocket)
[Log] Connecting to eJabberd... (main.js, line 8666)
[Log] 1: Websocket open (main.js, line 8626)
[Log] 1: _connect_cb was called (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 1: SASL authentication succeeded. (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626, x4)
[Log] eJabberd connected! (main.js, line 8687)
[Log] 1: _dataRecv called (main.js, line 8626) 

Logout...
[Log] Disconnecting from eJabberd... (main.js, line 8672)
[Log] 1: Disconnect was called because: logout (main.js, line 8626)
[Log] 1: _doDisconnect was called (main.js, line 8626)
[Log] 1: WebSockets _doDisconnect was called (main.js, line 8626)
[Log] Disconnected from eJabberd (main.js, line 8675)
[Log] 1: Websocket closed (main.js, line 8626)

Second attempt (fails, WebSocket)
[Log] Connecting to eJabberd... (main.js, line 8666)
[Log] 1: Websocket open (main.js, line 8626)
[Log] 1: _connect_cb was called (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] eJabberd authentication failed! (main.js, line 8693)
[Log] 3: WebSocket stream error: connection-timeout - Idle connection (main.js, line 8626)
[Log] eJabberd generic connection error! (main.js, line 8696)
[Log] 1: _doDisconnect was called (main.js, line 8626)
[Log] 1: WebSockets _doDisconnect was called (main.js, line 8626)
[Log] Disconnected from eJabberd (main.js, line 8675)
[Log] 1: Websocket closed (main.js, line 8626)


Successful first login (BOSH)
[Log] Connecting to eJabberd... (main.js, line 8666)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 1.0 posting (main.js, line 8626)
[Log] 0: request id 1.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 1.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 1.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 1.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 1 should now be removed (main.js, line 8626)
[Log] 0: request id 1.1 got 200 (main.js, line 8626)
[Log] 1: _connect_cb was called (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 2.0 posting (main.js, line 8626)
[Log] 0: request id 2.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 2.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 2.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 2.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 2 should now be removed (main.js, line 8626)
[Log] 0: request id 2.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 1: SASL authentication succeeded. (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 3.0 posting (main.js, line 8626)
[Log] 0: request id 3.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 3.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 3.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 3.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 3 should now be removed (main.js, line 8626)
[Log] 0: request id 3.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 4.0 posting (main.js, line 8626)
[Log] 0: request id 4.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 4.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 4.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 4.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 4 should now be removed (main.js, line 8626)
[Log] 0: request id 4.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 5.0 posting (main.js, line 8626)
[Log] 0: request id 5.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 5.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 5.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 5.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 5 should now be removed (main.js, line 8626)
[Log] 0: request id 5.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] eJabberd connected! (main.js, line 8687)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 6.0 posting (main.js, line 8626)
[Log] 0: request id 6.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 6.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 6.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 6.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 6 should now be removed (main.js, line 8626)
[Log] 0: request id 6.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 1: no requests during idle cycle, sending blank request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 7.0 posting (main.js, line 8626)
[Log] 0: request id 7.0 state changed to 1 (main.js, line 8626)

Logout...
[Log] Disconnecting from eJabberd... (main.js, line 8672)
[Log] 1: Disconnect was called because: logout (main.js, line 8626)
[Log] 1: _sendTerminate was called (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 2 requests (main.js, line 8626)
[Log] 0: _processRequest: first request has readyState of 1 (main.js, line 8626)
[Log] 0: request id 17.0 posting (main.js, line 8626)
[Log] 0: request id 17.0 state changed to 1 (main.js, line 8626)
[Log] 0: request id 17.0 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: _processRequest: first request has readyState of 1 (main.js, line 8626)
[Log] 0: request id 17 should now be removed (main.js, line 8626)
[Log] 0: request id 17.0 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 0: request id 16.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 16.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 16.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 16 should now be removed (main.js, line 8626)
[Log] 0: request id 16.1 got 200 (main.js, line 8626)
[Log] 1: _dataRecv called (main.js, line 8626)
[Log] 1: _doDisconnect was called (main.js, line 8626)
[Log] Disconnected from eJabberd (main.js, line 8675)

Second attempt (after logout, unsuccessful, BOSH)
[Log] Connecting to eJabberd... (main.js, line 8666)
[Log] 0: _throttledRequestHandler called with 1 requests (main.js, line 8626)
[Log] 0: request id 18.0 posting (main.js, line 8626)
[Log] 0: request id 18.0 state changed to 1 (main.js, line 8626)
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (b7e98bdb6711295ac7cd2c2d7a139415, line 0)
[Log] 0: request id 18.1 state changed to 2 (main.js, line 8626)
[Log] 0: request id 18.1 state changed to 3 (main.js, line 8626)
[Log] 0: request id 18.1 state changed to 4 (main.js, line 8626)
[Log] 0: removing request (main.js, line 8626)
[Log] 0: _throttledRequestHandler called with 0 requests (main.js, line 8626)
[Log] 0: request id 18 should now be removed (main.js, line 8626)
[Log] 0: request id 18.1 got 200 (main.js, line 8626)
[Log] 1: _connect_cb was called (main.js, line 8626)
[Log] 3: Server did not offer a supported authentication mechanism (main.js, line 8626)
[Log] eJabberd connection failed! (main.js, line 8669)
[Log] 1: _doDisconnect was called (main.js, line 8626)
[Log] Disconnected from eJabberd (main.js, line 8675) 

如您所见,使用 Bosh 时,调试器告诉我服务器没有提供任何合适的身份验证方法。
显然服务器不再监听传入的连接请求。但是,奇怪的是,如果我重新启动服务器,重新连接就会成功。看起来 strophe.js 即使在断开连接过程完成后仍然保持打开状态,关闭它的唯一方法是停止服务器。

我不确定这是 strophe.js 问题还是 ejabberd 配置问题,但我更倾向于考虑客户端问题(或我的代码中缺少的东西),因为外部客户端可以完美连接到服务器。

任何提示将不胜感激。

【问题讨论】:

    标签: angular ejabberd strophe


    【解决方案1】:

    知道了。
    我在这里发帖,作为对那些面临类似问题的人的回答。
    问题不是 Strophe.js,而是 jabber 服务器的配置。问题是缓存。

    来自 eJabber 文档 (here)

    auth_use_cache: false|true: 从 ejabberd 17.06 开始,缓存具有 接受了彻底的大修。一组新的而不是 extauth_cache variables 描述缓存行为,默认值为 now 真的。请注意,缓存会干扰维护的能力 每个帐户多个密码。因此,如果您的身份验证机制 支持应用程序特定的密码,缓存必须禁用。

    eJabberd 被配置为默认情况下对适用的所有内容使用缓存。
    因为,当我从我的 Web 应用程序注销时,我使用于身份验证的旧 JSON Web 令牌无效,所以 ejabber 会根据缓存值检查新凭据,从而发现不匹配。
    解决方案是像这样禁用缓存(在 ejabberd.yml 中)auth_use_cache: false

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多