Javascript, Websockets和XMPP客户端.如何让他们一起工作



我需要一个"Hello world!"示例,演示如何组合使用websocket s和ejabberd。所以,这就是我的位置:

  1. 我已经安装并运行ejabberd
  2. 我有两个帐户:"user1"one_answers"user2",密码为"123"
  3. 我可以在两个用户下运行psi plus客户端,我可以发送给自己的信息
  4. 我从ejabberd的官方网站知道它支持websockets
  5. 我知道有一个很流行的插件Strophe.js,很多人都在用连接ejabberd

,这是问题列表:

  1. 我不知道设置ejabberd配置的正确方法是什么(我猜,我安装了ejabberd和它的新版本配置位于ejabberd.yml)
  2. 我不知道我是否应该做具体的配置Apache服务器(代理,重写等)在许多论坛我已经看到了一些涉及到这样的操作的例子)
  3. 我不知道JavascriptC++Python代码是什么搭配这个谜题,这样我就可以做一个简单的connect to或send a message
嗯,我花了两天时间,完全白费了。无论我有什么配置设置,无论我有什么代码,我总是从FF得到一条消息:
Firefox can't establish connection to the server 
at ws://localhost:5280/http-ws

是的,我编辑了ejabberd.yml,所以它有这些行:

requests_handlers:
   "http-ws/": ejabberd_http_ws

我也编辑了apache的配置,所以我有:

ProxyRequests off
ProxyPass /http-ws/ http://localhost:5280/http-ws/
ProxyPassReverse /http-ws/ http://localhost:5280/http-ws/
RewriteEngine on
RewriteRule http-ws/ http://localhost:5280/http-ws/

确实,我重新启动了apache和ejabberd。在我的代码中,我有:

var SocketUrl = 'ws://localhost:5280/http-ws'
...other standard stuff

我想,我尝试了几十*几十种组合,但没有一种有效。所以,我需要一个分步指导来回答这三个问题:

  1. 如何设置ejabberd
  2. 如何设置Apache
  3. 如何原始的例子(在JavaScript)应该看起来像

编辑

我现在的配置:

1. ejabberd.yml:
...
hosts:
 - "localhost"
....
listen:
....
  -
    port: 5280
    ip: "::"
    module: ejabberd_http
    request_handlers:
     "/http-ws": ejabberd_http_ws
    web_admin: true
    http_poll: true
    http_bind: true
....
acl:
  admin:
    user:
     - "admin": "localhost"
access:
 configure:
    admin: allow
2. apache2.conf
<Directory />
  AllowOverride All
  Allow From All
</Directory>
<Directory /var/www/site>
  AllowOverride All
  Allow From All
</Directory>
3. apache2/sites-available/000-default.conf
<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/site
    <Directory /var/www/site>
       Options  +Indexes +MultiViews
    </Directory>
    ProxyRequests off
    AddDefaultCharset UTF-8
    ProxyPass /http-ws/ http://127.0.0.1:5280/http-ws/
    ProxyPassReverse /http-ws/ http://127.0.0.1:5280/http-ws/
    RewriteEngine on
    RewriteRule /http-ws/http://127.0.0.1:5280/http-ws/
  ...

最后这是我的代码:

window.onload = function(){
     var SocketUrl = 'ws://localhost:5280/http-ws/';
     var connection = null;
     function onConnect(status){
       if (status == Strophe.Status.CONNECTING) {
     alert('Strophe is connecting.');
       } else if (status == Strophe.Status.CONNFAIL) {
     alert('Strophe failed to connect.');
       } else if (status == Strophe.Status.DISCONNECTING) {
     alert('Strophe is disconnecting.');
       } else if (status == Strophe.Status.DISCONNECTED) {
     alert('Strophe is disconnected.');
       } else if (status == Strophe.Status.CONNECTED) {
     alert('Strophe is connected.');
       }
    }
    var button = document.getElementById("connect");
    button.onclick = function(){
      connection = new Strophe.Connection(SocketUrl);
      var jid = document.getElementById("jid").value;
      var pass = document.getElementById("pass").value;
      connection.connect(jid, pass, onConnect);
    }
  }
因此,在运行这个示例时,我总是得到这些警告:
Strophe is connecting
Strophe failed to connect
Strophe is disconnected

在控制台中,我看到这个错误消息:

Firefox can't establish a connection to the server at ws://localhost:5280/http-ws/

Ejabberd日志

这是我在ejabberd日志中的内容:

2015-08-20 12:52:40.558 [error] <0.448.0> CRASH REPORT Process <0.448.0> with 0 neighbours crashed with reason: call to undefined function ejabberd_http_ws:process([], {request,'GET',[<<"http-ws">>],[{nokey,<<>>}],{<<>>,<<>>},undefined,<<"en-US">>,<<>>,{{0,0,0,0,...},...},...})
2015-08-20 12:52:40.559 [error] <0.326.0> Supervisor ejabberd_http_sup had child undefined started with {ejabberd_http,start_link,undefined} at <0.448.0> exit with reason undef in context child_terminated

我想,我应该强调日志中的这一行:

call to undefined function ejabberd_http_ws

我试图在ejabberd.yml中启用module节下的此模块,如:

modules:
   ...
   mod_http_ws: {}

我认为应该有效,如果文档没有说谎的话。然而,在这种情况下,我无法重新启动ejabberd,在它的日志文件中,我现在看到这个消息:

 initialization was aborted because a module start failed

这是一些关于ejabberd包的信息,我只是用命令安装:

$ apt-get -y install ejabberd

那么,$ dpkg -s ejabberd返回

Package: ejabberd
Status: install ok installed
Priority: optional
Section: net
Installed-Size: 6405
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 14.07-4ubuntu1
Provides: xmpp-server
Depends: adduser, erlang-base (>= 1:15.b) | erlang-abi-17.0, erlang-asn1 (>= 1:17.3-dfsg), erlang-base (>= 1:17.3-dfsg) | erlang-base-hipe (>= 1:17.3-dfsg), erlang-crypto (>= 1:17.3-dfsg), erlang-inets (>= 1:17.3-dfsg), erlang-mnesia (>= 1:17.3-dfsg), erlang-odbc (>= 1:17.3-dfsg), erlang-public-key (>= 1:17.3-dfsg), erlang-ssl (>= 1:17.3-dfsg), erlang-syntax-tools (>= 1:17.3-dfsg), openssl, ucf, debconf (>= 0.5) | debconf-2.0, erlang-lager, erlang-jiffy, erlang-p1-cache-tab, erlang-p1-iconv, erlang-p1-mysql, erlang-p1-pam, erlang-p1-pgsql, erlang-p1-sip, erlang-p1-stringprep, erlang-p1-stun, erlang-p1-tls, erlang-p1-utils, erlang-p1-xml, erlang-p1-yaml, erlang-p1-zlib, erlang-xmlrpc
Recommends: ejabberd-contrib
Suggests: libunix-syslog-perl, imagemagick | graphicsmagick-imagemagick- compat
Conflicts: ejabberd-mod-shared-roster-ldap
Conffiles:
 /etc/default/ejabberd 49352468a39da545ad13586af05877f9
 /etc/ejabberd/inetrc a8de3c20d2ac990c8f319907b340d6a2
 /etc/init.d/ejabberd 58aa53c895ae2250e80ea16769db0417
 /etc/logrotate.d/ejabberd d2a0a63e544aabfb797f718471c6d173
 /etc/ufw/applications.d/ejabberd abc263fcde39ff65e9b5722be81db8ff
Description: distributed, fault-tolerant Jabber/XMPP server written in Erlang
 ejabberd is a distributed, fault-tolerant Jabber/XMPP server written in Erlang.

$ service ejabberd status返回

● ejabberd.service - LSB: Starts ejabberd jabber server
Loaded: loaded (/etc/init.d/ejabberd)
Active: active (exited) since Thu 2015-08-20 13:32:27 PDT; 12h ago
 Docs: man:systemd-sysv-generator(8)
Process: 12701 ExecStop=/etc/init.d/ejabberd stop (code=exited, status=0/SUCCESS)
Process: 13716 ExecStart=/etc/init.d/ejabberd start (code=exited, status=0/SUCCESS)
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 156: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 157: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 158: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 159: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 160: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 161: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 163: /etc/eja...d
Aug 20 13:32:22 ubuntu ejabberd[13716]: /usr/sbin/ejabberdctl: 164: /etc/eja...d
Aug 20 13:32:27 ubuntu ejabberd[13716]: done.
Aug 20 13:32:27 ubuntu systemd[1]: Started LSB: Starts ejabberd jabber server.

Ejabberd从15.03版本开始支持websockets -这解决了上面的答案。

这与python或c++无关——这个难题只是关于配置Ejabberd来支持websockets,并选择使用代理来处理websockets流量。

在ejabjjerd下面。Yml节,模块:ejabberd_http add

request_handlers:
  "/http-ws": ejabberd_http_ws

这将在端口5280可用:/http-ws

如果不方便,您可以使用apache或nginx从80端口代理。

对于nginx,在虚拟主机中,您需要这样做,其中JABBERIP是ejabberd的ip地址。这将代理从标准http端口80到ejabberd的websocket连接,该连接配置为处理websocket。

location /http-ws/ {
 proxy_pass http://JABBERIP:5280;  // this is 
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection "upgrade";
}

你可能还需要调整ejabberd中的websocket设置。我把这些放在文件的顶部..

websocket_ping_interval: 60
websocket_timeout: 86400

设置strophe超出了这个答案的范围,但关键的一点是设置连接使用websockets,如果浏览器支持这一点。下面的代码片段来自于一个angularjs应用——不过你应该明白了……SocketUrl是如上所示的/http-ws位置的公共位置。这可能是:5280版本或代理到端口80的版本。

        if (window.WebSocket && (passwd != 'undefined' && passwd != null)) {
            $this.connection = new Strophe.Connection($this.SocketUrl);
            $this.connection.connect(user_info.username+'@'+$this.jabberUrl, passwd, $this.onConnect.bind($this));
        } else {
            UserService.getJabberData().then(function (response) {
                var jabber = response.data;
                $this.connection = new Strophe.Connection($this.BOSHUrl);
                $this.connection.attach(jabber.jid, jabber.sid, jabber.rid, $this.onConnect.bind($this));
            });
        }

也有用于python和其他语言的xmpp库-尽管如果你正在考虑构建一个在web浏览器中运行的应用程序,strophe是一个很好的选择。

相关内容

  • 没有找到相关文章

最新更新