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

 

原文地址:https://www.cnblogs.com/qdlixuecai/p/5533828.html