• Android XMPP服务器, BOSH(Http-Binding)和WEB客户端搭建


    目标: 搭建一个XMPP服务器, 实现在web page上用javascript与自己XMPP服务器通信, 匿名登录并与任何一个XMPP(Jabber)帐户通信. (Gtalk目前尚有问题)

    XMPP服务器可能不是必须的(见下文, 我没有尝试)

    环境与配置:

    XMPP服务器:ejabberd文档
    HTTP-Binding: 使用ejabberd搭建, 5280端口.
    Javascript Client:Strophe文档

    安装Ejabberd

    yuminstallejabberd
    #apt-get install ejabberd

    编辑配置文件: /etc/ejabberd/ejabberd.cfg, 这是个era lang格式配置文件, 行注释符号是%. 请参考ejabberd文档.

    下面是默认配置文件里我修改过部分:

    %%debug
    {loglevel, 5}.
    {hosts, ["sagan.me"]}.
    {host_config, "sagan.me", [{auth_method, [anonymous,internal]},{anonymous_protocol, sasl_anon}]}.
    
    {listen,
     [
      {5222, ejabberd_c2s, [
                            {certfile, "/path/to/ssl/cert.pem"},
                            %%starttls,
                            starttls_required,
                            {access, c2s},
                            {shaper, c2s_shaper},
                            {max_stanza_size, 65536}
                           ]},
      {5269, ejabberd_s2s_in, [
                               {shaper, s2s_shaper},
                               {max_stanza_size, 131072}
                              ]},
      {{5280, "127.0.0.1"}, ejabberd_http, [
                            {request_handlers, [{["http-bind"], mod_http_bind}]},
                             captcha
                            ]}
    
     ]}.
    {s2s_use_starttls, true}.
    {s2s_certfile, "/path/to/ssl/cert.pem"}.
    {s2s_default_policy, allow}.
    {auth_method, [internal, anonymous]}.

    上面配置中, 声明监听127.0.0.1(本地IP地址) 5280端口为http-binding (BOSH)服务地址, 路径是"http-bind", 即服务实际URI是"http://127.0.0.1:5280/http-bind". 然后需要在web服务器配置中用mod_proxy或mod_rewrite将80或443端口上对 "/http-bind" 访问转发到"http://127.0.0.1:5280/http-bind", 因为由于浏览器同源限制, yourdomain.com:80上的web page是无法直接向yourdomain.tld:5280提交ajax请求的. ( 所以在上面配置中把ejabberd http-bind监听的端口设为了127.0.0.1:5280, 即不能从外部直接访问)

    添加域名DNS SRV记录

    这一步是必须的, 否则搭建的XMPP服务器基本上无法与大多数其它服务器或客户端通信. (插一句: Google Apps Talk基于XMPP平台, 如果不设置域名SRV记录的话, 就只能够用Gtalk登录(无法使用其它XMPP客户端), 而且只能和gmail.com或其它Google Apps域名的帐户通信)

    _xmpp-client._tcp.sagan.me. 86400 IN SRV 10 0 5222 sagan.me.
    _xmpp-server._tcp.sagan.me. 86400 IN SRV 10 0 5269 sagan.me.

    5269和5222是XMPP在ICANN注册的标准端口.

    修改WEB服务器配置

    我的Lighttpd ModProxy配置:

    proxy.server = (
            "/http-bind" => ( (
                    "host" => "127.0.0.1",
                    "port" => 5280
            ) )
    )

    应该也可以用web服务器直接转发请求到外部某个公开的Jabber (XMPP)服务器 http-bind地址, 我没有尝试. (基本上找不到公开的提供http-bind的XMPP服务器)

    使用Javascript客户端

    上面ejabberd配置里开启了匿名登录(ANOYMOUS mechanism), 最终目的就是为了在web page中匿名访问服务并向任何一个XMPP帐户发送消息.

    下载Strophe JS库并上传到你的域名目录下(这个库只有一个文件strophe.js), 下面这个测试例子修改自Strophe examples目录下echobot.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Strophe.js Echobot Example</title>
    <script type='text/javascript'
    src='http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js'></script>
    <script type='text/javascript'
    src='../strophe.js'></script>
    <script type='text/javascript'
    src='echobot.js'></script>
    </head>
    <body>
    <div id='login' style='text-align: center'>
    <form name='cred'>
    <label for='jid'>JID:</label>
    <input type='text' id='jid' value="sagan.me" />
    <label for='pass'>Password:</label>
    <input type='password' id='pass' />
    <input type='button' id='connect' value='connect' />
    </form>
    </div>
    <hr />
    <div id='log'></div>
    </body>
    </html>

    看echobot.js

    varBOSH_SERVICE ='/xmpp-httpbind';
    varconnection =null;
    functionlog(msg)
    {
    $('#log').append('<div></div>').append(document.createTextNode(msg));
    }
    functiononConnect(status)
    {
    if(status== Strophe.Status.CONNECTING){
    log('Strophe is connecting.');
    }elseif(status== Strophe.Status.CONNFAIL){
    log('Strophe failed to connect.');
    $('#connect').get(0).value='connect';
    }elseif(status== Strophe.Status.DISCONNECTING){
    log('Strophe is disconnecting.');
    }elseif(status== Strophe.Status.DISCONNECTED){
    log('Strophe is disconnected.');
    $('#connect').get(0).value='connect';
    }elseif(status== Strophe.Status.CONNECTED){
    log('Strophe is connected.');
    log('ECHOBOT: Send a message to '+ connection.jid+
    ' to talk to me.');
    connection.addHandler(onMessage,null,'message',null,null, null);
    connection.send($pres().tree());
    varreply = $msg({to:"ono@oogami.name", from: connection.jid, type:'chat'}).c("body").t("Test Chat Message");
    connection.send(reply.tree());
    }
    }
    functiononMessage(msg){
    varto = msg.getAttribute('to');
    varfrom = msg.getAttribute('from');
    vartype = msg.getAttribute('type');
    varelems = msg.getElementsByTagName('body');
    if(type =="chat"&&elems.length>0){
    varbody = elems[0];
    log('ECHOBOT: I got a message from '+ from +': '+
    Strophe.getText(body));
    varreply = $msg({to: from, from: to, type:'chat'})
    .cnode(Strophe.copyElement(body));
    connection.send(reply.tree());
    log('ECHOBOT: I sent '+ from +': '+ Strophe.getText(body));
    }
    // we must return true to keep the handler alive.
    // returning false would remove it after it finishes.
    returntrue;
    }
    $(document).ready(function(){
    connection =newStrophe.Connection(BOSH_SERVICE);
    // Uncomment the following lines to spy on the wire traffic.
    //connection.rawInput = function (data) { log('RECV: ' + data); };
    //connection.rawOutput = function (data) { log('SEND: ' + data); };
    // Uncomment the following line to see all the debug output.
    //Strophe.log = function (level, msg) { log('LOG: ' + msg); };
    $('#connect').bind('click',function(){
    varbutton = $('#connect').get(0);
    if(button.value=='connect'){
    button.value='disconnect';
    connection.connect($('#jid').get(0).value,
    $('#pass').get(0).value,
    onConnect);
    }else{
    button.value='connect';
    connection.disconnect();
    }
    });
    });

    将ono@oogami.name修改为一个测试Jabber帐号. 然后用浏览器打开echobot.html, 点击Connect按钮, Strophe就会匿名登录到刚刚建立的ejabber服务器( sagan.me ), 并向 "ono@oogami.name"这个帐号发送一条"Test Message"的信息.

    另: 测试匿名登录向somebody@gtalk.com 发送消息失败, log里显示Gtalk服务器返回信息是503 error, Service-Unavailable, 但如果正常登录并添加Gtalk为好友的话则可以. Gtalk禁止了匿名用户向其发送消息? 我还在查资料中.

    我准备用Javascript写一个简单的XMPP WEB匿名客户端, 实现允许访客直接与Gtalk和Facebook Chat通信等功能

    http://www.ibm.com/developerworks/cn/xml/tutorials/x-realtimeXMPPtut/index.html

  • 相关阅读:
    kali linux源大全
    kali2016.2(debian)快速安装mysql5.7.17
    hadoop java上传文件
    HDFS客户端的权限错误:Permission denied
    hadoop fs命令
    解决Unable to load native-hadoop library for your platform
    并查集。路径压缩 算法运用学习(一)
    HBase快速安装
    记一次zookeeper单机伪集群分布
    ZooKeeper使用命令大全
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5897497.html
Copyright © 2020-2023  润新知