• ejabberd服务端开发笔记


    网上一搜一大陀ejabberd安装配置的,扩展开发的资料少之又少,写个笔记记录一下。

    xmpp protocal: http://xmpp.org/xmpp-protocols/xmpp-extensions/

    安装与配置:

    http://www.process-one.net/docs/ejabberd/guide_en.html

    默认配置文件在 /etc/ejabberd/ejabberd.cfg

    1

    git clone git://github.com/processone/ejabberd.git ejabberd
    cd ejabberd
    git checkout -b 2.1.x origin/2.1.x

    2

     sudo apt-cache search libyaml

    sudo apt-get install libyaml-dev

    3. cd ejabberd/src

    ./configure

    make

    报错:erl_driver.h: No such file or directoryERLANG_CFLAGS=

    vi Makefile发现ERLANG_CFLAGS和ERLANG_LIBS所指目录不对,居然使用了我编译erlang时的源文件而没有使用/usr/local/...

    解决方法也很简单,把编译erlang用的源文件(otp-src-R16B01)删除,再次./configure即可。因为这样configure的时候就不会找到

    4.

    sudo make install

    5.

    The files and directories created are, by default:

    /etc/ejabberd/
    Configuration directory:
    ejabberd.yml
    ejabberd configuration file
    ejabberdctl.cfg
    Configuration file of the administration script
    inetrc
    Network DNS configuration file
    /lib/ejabberd/
    ebin/
    Erlang binary files (*.beam)
    include/
    Erlang header files (*.hrl)
    priv/
    Additional files required at runtime
    bin/
    Executable programs
    lib/
    Binary system libraries (*.so)
    msgs/
    Translation files (*.msgs)
    /sbin/ejabberdctl
    Administration script (see section 4.1)
    /share/doc/ejabberd/
    Documentation of ejabberd
    /var/lib/ejabberd/
    Spool directory:
    .erlang.cookie
    Erlang cookie file (see section 5.3)
    acl.DCD, ...
    Mnesia database spool files (*.DCD, *.DCL, *.DAT)
    /var/log/ejabberd/
    Log directory (see section 7.1):
    ejabberd.log
    ejabberd service log
    erlang.log
    Erlang/OTP system log

    6. 

    ejabberdctl start
    
    ejabberdctl status
    The node ejabberd@localhost is started with status: started
    ejabberd is running in that node
    
    ejabberdctl stop

    接下来需要使用客户端进行简单的测试,网上搜了一下,选择了smack。

    首先写一个注册功能: 

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public boolean register(String username, String password) {  
    2.     try {  
    3.         ConnectionConfiguration config = new ConnectionConfiguration(  
    4.                 "192.168.17.102", 5222);  
    5.         connection = new XMPPConnection(config);  
    6.         connection.connect();  
    7.         System.out.println("connect ok, user,pass:" + username + " "  
    8.                 + password);  
    9.         AccountManager am = connection.getAccountManager();  
    10.         am.createAccount(username, password);  
    11.         connection.disconnect();  
    12.     } catch (Exception ex) {  
    13.         ex.printStackTrace();  
    14.         return false;  
    15.     }  
    16.       


    发现connection ok但是无法注册。检查配置文件,vi /etc/ejabberd/ejabberd.cfg

    [plain] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. {mod_register, [  
    2.                  %%  
    3.                  %% Protect In-Band account registrations with CAPTCHA.  
    4.                  %%  
    5.                  {captcha_protected, true},  
    6.   
    7.                  %%  
    8.                  %% Set the minimum informational entropy for passwords.  
    9.                  %%  
    10.                  %%{password_strength, 32},  
    11.   
    12.                  %%  
    13.                  %% After successful registration, the user receives  
    14.                  %% a message with this subject and body.  
    15.                  %%  
    16.                  {welcome_message, {"Welcome!",  
    17.                                     "Hi. Welcome to this XMPP server."}},  
    18.   
    19.                  %%  
    20.                  %% When a user registers, send a notification to  
    21.                  %% these XMPP accounts.  
    22.                  %%  
    23.                  %%{registration_watchers, ["admin1@example.org"]},  
    24.   
    25.                  %%  
    26.                  %% Only clients in the server machine can register accounts  
    27.                  %%  
    28.                  {ip_access, [{allow, "127.0.0.0/8"},  
    29.                               {deny, "0.0.0.0/0"}]},  
    30.   
    31.                  %%  
    32.                  %% Local c2s or remote s2s users cannot register accounts  
    33.                  %%  
    34.                  %%{access_from, deny},  
    35.                  {access, register}  
    36.                 ]},  


    将{ip_access, [..., {deny, "0.0.0.0/0"}]}改为allow,再次运行注册代码,发现依然失败。然后改为使用如下代码,注册成功:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public void register2(String username, String password, String email,  
    2.         String fullName) {  
    3.     try {  
    4.         ConnectionConfiguration config = new ConnectionConfiguration(  
    5.                 "192.168.17.102", 5222);  
    6.         connection = new XMPPConnection(config);  
    7.         connection.connect();  
    8.   
    9.         Registration reg = new Registration();  
    10.         reg.setType(IQ.Type.SET);  
    11.         reg.setTo(connection.getServiceName());  
    12.         // attributes.put("username", username);  
    13.         // attributes.put("password", password);  
    14.         // reg.setAttributes(attributes);  
    15.         Map<String, String> attr = new HashMap<String, String>();  
    16.         attr.put("username", username);  
    17.         attr.put("password", password);  
    18.         attr.put("email", email);  
    19.         attr.put("name", fullName);  
    20.         reg.setAttributes(attr);  
    21.   
    22.         PacketFilter filter = new AndFilter(new PacketIDFilter(  
    23.                 reg.getPacketID()), new PacketTypeFilter(IQ.class));  
    24.         PacketCollector collector = connection  
    25.                 .createPacketCollector(filter);  
    26.         connection.sendPacket(reg);  
    27.   
    28.         IQ result = (IQ) collector.nextResult(SmackConfiguration  
    29.                 .getPacketReplyTimeout());  
    30.         // Stop queuing results  
    31.         collector.cancel();// 停止请求results(是否成功的结果)  
    32.         if (result == null) {  
    33.             System.out  
    34.                     .println("xmppMainRegiter”, “No response from server.");  
    35.         } else if (result.getType() == IQ.Type.ERROR) {  
    36.             if (result.getError().toString()  
    37.                     .equalsIgnoreCase("conflict(409)")) {  
    38.                 System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "  
    39.                         + result.getError().toString());  
    40.                 System.out.println("conflict");  
    41.             } else {  
    42.                 System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "  
    43.                         + result.getError().toString());  
    44.                 System.out.println("注册失败");  
    45.             }  
    46.         } else if (result.getType() == IQ.Type.RESULT) {  
    47.             System.out.println("注册成功");  
    48.         }  
    49.     } catch (Exception ex) {  
    50.         ex.printStackTrace();  
    51.     }  
    52. }  

    关于ejabberd各模块的测试,因为mod_*均为gen_*, 可以使用rpc:call/4进行测试某些功能。但是erlang节点的互通需要-setcookie,

    vi /var/lib/ejabberd/.erlang.cookie 

    可以查看ejabberd节点的cookie值,这里查到为FBSFDTMHVUJTXLNXFUE

    启动erlang shell, erl -sname test -setcookie FBSFDTMHVUJTXLNXFUE

      > rpc:call(ejabberd@localhost, ejabberd_captcha, is_feature_available, [], 10).
      > true

    成功。

    ejabberd的参考资料少之又少,刚才研究了下如何获取验证码。

    首先要在/etc/ejabberd/ejabberd.cfg中开启验证。

    mod_register:

    [plain] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. {captcha_protected, true}  
    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. %%%.   =======  
    2. %%%'   CAPTCHA  
    3.   
    4. %%  
    5. %% Full path to a script that generates the image.  
    6. %%  
    7. {captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.  
    8.   
    9. %%  
    10. %% Host for the URL and port where ejabberd listens for CAPTCHA requests.  
    11. %%  
    12. {captcha_host, "192.168.17.102:5280"}.  
    13.   
    14. %%  
    15. %% Limit CAPTCHA calls per minute for JID/IP to avoid DoS.  
    16. %%  
    17. {captcha_limit, 5}.  


    然后看了下mod_register和ejabberd_captcha的代码,把注册请求的IQ.Type.SET改为IQ.Type.GET即可获取验证码信息,得到xml响应如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <iq id="hLfY6-0" from="192.168.17.102" type="result">  
    2.   <query xmlns="jabber:iq:register">  
    3.     <instructions>You need a client that supports x:data and CAPTCHA to register</instructions>  
    4.     <xmlns="jabber:x:data" type="form">  
    5.       <instructions>Choose a username and password to register with this server</instructions>  
    6.       <field var="FORM_TYPE" type="hidden">  
    7.         <value>urn:xmpp:captcha</value>  
    8.       </field>  
    9.       <field label="User" var="username" type="text-single">  
    10.         <required/>  
    11.       </field>  
    12.       <field label="Password" var="password" type="text-private">  
    13.         <required/>  
    14.       </field>  
    15.       <field type="fixed">  
    16.         <value>If you don't see the CAPTCHA image here, visit the web page.</value>  
    17.       </field>  
    18.       <field var="captchahidden" type="hidden">  
    19.         <value>workaround-for-psi</value>  
    20.       </field>  
    21.       <field label="CAPTCHA web page" var="url" type="text-single">  
    22.         <value>http://192.168.17.102:5280/captcha/2824232941/image</value>  
    23.       </field>  
    24.       <field var="from" type="hidden">  
    25.         <value>192.168.17.102</value>  
    26.       </field>  
    27.       <field var="challenge" type="hidden">  
    28.         <value>2824232941</value>  
    29.       </field>  
    30.       <field var="sid" type="hidden">  
    31.         <value>hLfY6-0</value>  
    32.       </field>  
    33.       <field label="Enter the text you see" var="ocr">  
    34.         <required/>  
    35.       </field>  
    36.     </x>  
    37.     <data xmlns="urn:xmpp:bob"/>  
    38.   </query>  
    39. </iq>  


    验证码图片为

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. http://192.168.17.102:5280/captcha/2824232941/image  

    Over!

    控制台输出:

     vi /sbin/ejabberdctl 

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. start ()  
    2. {  
    3.     checknodenameusage  
    4.     [ "$?" -eq 0 ] && echo " ERROR: The node '$ERLANG_NODE' is already running." && return 1  
    5.   
    6.     $EXEC_CMD "$ERL   
    7.       $NAME $ERLANG_NODE   
    8.       -noinput -detached   
    9.       -pa $EJABBERD_EBIN_PATH   
    10.       -mnesia dir "\"$SPOOLDIR\""   
    11.       $KERNEL_OPTS   
    12.       -s ejabberd   
    13.       -sasl sasl_error_logger \{file,\"$SASL_LOG_PATH\"\}   
    14.       $ERLANG_OPTS $ARGS "$@""  
    15. }  

    去掉-noinput -detached

     

  • 相关阅读:
    Ionic
    图片破碎 效果 修正
    去掉浏览器右侧动滚条宽度对页面的影响
    ng 依赖注入
    ng 通过factory方法来创建一个心跳服务
    ng 自定义服务
    ng $http 和远程服务器通信的一个服务。
    ng $interval(周期性定时器) $timeout(延迟定时器)
    ng $scope与$rootScope的关系
    函数重载
  • 原文地址:https://www.cnblogs.com/qdlixuecai/p/5533828.html
Copyright © 2020-2023  润新知