Javascript、WebSocket和XMPP客户端。如何让他们一起工作?

Javascript、WebSocket和XMPP客户端。如何让他们一起工作?,javascript,websocket,xmpp,ejabberd,Javascript,Websocket,Xmpp,Ejabberd,我需要一个你好的世界!这个示例演示了如何结合使用WebSocket和ejabberd。这就是我现在的处境: 我已安装并运行ejabberd 我有两个帐户:user1和user2,密码为123 我能够在两个用户下运行psi plus客户端,并且我可以发送 给自己的信息 我从ejabberd的官方网站上知道它支持WebSocket 我知道有很多人使用的流行插件Strophe.js 连接到ejabberd 以下是问题列表: 我不知道设置ejabberd配置的正确方法是什么 我猜,我安装了新版本的eja

我需要一个你好的世界!这个示例演示了如何结合使用WebSocket和ejabberd。这就是我现在的处境:

我已安装并运行ejabberd 我有两个帐户:user1和user2,密码为123 我能够在两个用户下运行psi plus客户端,并且我可以发送 给自己的信息 我从ejabberd的官方网站上知道它支持WebSocket 我知道有很多人使用的流行插件Strophe.js 连接到ejabberd 以下是问题列表:

我不知道设置ejabberd配置的正确方法是什么 我猜,我安装了新版本的ejabberd及其 配置位于ejabberd.yml中 我不知道是否应该进行具体配置 Apache服务器代理、重写等功能-在许多论坛中 我见过一些涉及这种操纵的例子 我不知道Javascript或C++或Python代码将是什么 把这个拼图拼起来,这样我就可以做一个简单的 连接到或发送消息 嗯,我花了两天的时间,完全没有用。无论我有什么配置设置,也不管我有什么代码,我总是从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
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);
    }
  }
我想,我尝试了几十种组合,但没有一种有效。因此,我需要一个循序渐进的指导来回答这三个问题:

如何设置ejabberd 如何设置Apache 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/

  ...
因此,在运行此示例时,我总是收到以下警报:

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.yml中的模块部分启用此模块,如下所示:

如果不是撒谎,我认为这应该行得通。但是,在这种情况下,我无法重新启动ejabberd,在其日志文件中,我现在看到以下消息:

 initialization was aborted because a module start failed
包装

以下是有关我仅使用以下命令安装的ejabberd软件包的一些信息:

$ apt-get -y install ejabberd
因此,$dpkg-s ejabberd返回


Ejabberd从15.03版开始支持WebSocket,解决了上述问题

这与Python或C++无关。这个谜题只是关于配置Ejabberd来支持WebSoCube,并且可选地使用代理来处理WebSoCuffs流量。 在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.yml中的websocket设置-我将这些设置放在文件的顶部

websocket_ping_interval: 60
websocket_timeout: 86400

设置strophe超出了此答案的范围,但关键在于设置连接以使用WebSocket(如果浏览器支持此功能)。下面的snippit来自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是一个很好的选择

明天我将开始一个非常大的悬赏活动,因为我需要一个关于这个主题的一步一步的新鲜和深入的指导。所以,赶快去获取一些巨大的因果报应:顺便说一下,如果你知道如何在Python或C++中实现类似的东西,并且可以共享一些工作代码,我会接受这个答案。SoCKETURL是/HTTP WS位置的公共位置。请你详细说明一下好吗?SocketUrl看起来像什么?类似于ws://host:port/httpws或http://host:port/http-ws?我问这个问题,因为我在不同的例子中看到了多个变体,但是所有的例子都是断章取义的,没有人说过关于ejabberd.ymlAnd的话,它不应该是proxy_pass吗http://JABBERIP:5280/http-ws/?我这样问是因为在许多Apache示例中,我看到了类似于RewritePass http bind/http://JABBERIP:5280/http-绑定/;重写规则http绑定/http://JABBERIP:5280/http-绑定/使用我的示例,客户端应用程序的socketurl的位置将是ws://host:port/httpws-如果使用代理,这将通过端口80,因此不需要指定端口。如果直接寻址ejabberd服务器,则需要包含端口。代理端口80的主要优点是,它将更受代理和公司防火墙等后台人员的支持。在我的设置中,代理
_pass在没有尾部斜杠的情况下运行良好。。有了ApacheYMMV,您能看到我问题的更新版本吗?谢谢
● 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.
request_handlers:
  "/http-ws": ejabberd_http_ws
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";
}
websocket_ping_interval: 60
websocket_timeout: 86400
        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));
            });
        }