断开连接后Strophe.js无法重新连接

时间:2018-09-18 11:47:08

标签: angular ejabberd strophe

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

这是我用来管理连接的代码段(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 config问题,但是我更倾向于考虑客户端问题(或者我的代码中缺少的东西),因为外部客户端可以完美地连接到服务器。

任何提示将不胜感激。

1 个答案:

答案 0 :(得分:1)

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

从eJabber文档(here

  

auth_use_cache:false | true:从ejabberd 17.06开始,缓存具有   进行了彻底的大修。一组新的而不是extauth_cache   变量描述缓存行为,默认值现在是   真正。请注意,缓存会影响维护能力   每个帐户有多个密码。所以如果您的身份验证机制   支持应用程序专用密码,必须禁用缓存。

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