网上一搜一大陀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。

首先写一个注册功能:

  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. }

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

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

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

  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. Registration reg = new Registration();
  9. reg.setType(IQ.Type.SET);
  10. reg.setTo(connection.getServiceName());
  11. // attributes.put("username", username);
  12. // attributes.put("password", password);
  13. // reg.setAttributes(attributes);
  14. Map<String, String> attr = new HashMap<String, String>();
  15. attr.put("username", username);
  16. attr.put("password", password);
  17. attr.put("email", email);
  18. attr.put("name", fullName);
  19. reg.setAttributes(attr);
  20. PacketFilter filter = new AndFilter(new PacketIDFilter(
  21. reg.getPacketID()), new PacketTypeFilter(IQ.class));
  22. PacketCollector collector = connection
  23. .createPacketCollector(filter);
  24. connection.sendPacket(reg);
  25. IQ result = (IQ) collector.nextResult(SmackConfiguration
  26. .getPacketReplyTimeout());
  27. // Stop queuing results
  28. collector.cancel();// 停止请求results(是否成功的结果)
  29. if (result == null) {
  30. System.out
  31. .println("xmppMainRegiter”, “No response from server.");
  32. } else if (result.getType() == IQ.Type.ERROR) {
  33. if (result.getError().toString()
  34. .equalsIgnoreCase("conflict(409)")) {
  35. System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "
  36. + result.getError().toString());
  37. System.out.println("conflict");
  38. } else {
  39. System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "
  40. + result.getError().toString());
  41. System.out.println("注册失败");
  42. }
  43. } else if (result.getType() == IQ.Type.RESULT) {
  44. System.out.println("注册成功");
  45. }
  46. } catch (Exception ex) {
  47. ex.printStackTrace();
  48. }
  49. }

关于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:

  1. {captcha_protected, true}
  1. %%%.   =======
  2. %%%'   CAPTCHA
  3. %%
  4. %% Full path to a script that generates the image.
  5. %%
  6. {captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
  7. %%
  8. %% Host for the URL and port where ejabberd listens for CAPTCHA requests.
  9. %%
  10. {captcha_host, "192.168.17.102:5280"}.
  11. %%
  12. %% Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
  13. %%
  14. {captcha_limit, 5}.

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

  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. <x 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>

验证码图片为

  1. http://192.168.17.102:5280/captcha/2824232941/image

Over!

控制台输出:

vi /sbin/ejabberdctl

  1. start ()
  2. {
  3. checknodenameusage
  4. [ "$?" -eq 0 ] && echo "\nERROR: The node '$ERLANG_NODE' is already running." && return 1
  5. $EXEC_CMD "$ERL \
  6. $NAME $ERLANG_NODE \
  7. -noinput -detached \
  8. -pa $EJABBERD_EBIN_PATH \
  9. -mnesia dir \"\\\"$SPOOLDIR\\\"\" \
  10. $KERNEL_OPTS \
  11. -s ejabberd \
  12. -sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
  13. $ERLANG_OPTS $ARGS \"$@\""
  14. }

去掉-noinput -detached

ejabberd服务端开发笔记的更多相关文章

  1. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)

    前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架.本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在<Swift3.0服务端开发(一)>这篇 ...

  3. 在线教学、视频会议 Webus Fox(2) 服务端开发手册

    上次在<在线教学.视频会议软件 Webus Fox(1)文本.语音.视频聊天及电子白板基本用法>里介绍了软件的基本用法.本文主要介绍服务器端如何配置.开发. 1. 配置 1.1 IIS配置 ...

  4. Android 服务端开发之开发环境配置

    Android 服务端开发之开发环境配置 这里是在Eclipse的基础上安装PhpEclipse插件方法,PHPEclipse是Eclipse的 一个用于开发PHP的插件.当然也可以采用Java开发a ...

  5. Swift3.0服务端开发(三) Mustache页面模板与日志记录

    本篇博客主要介绍如果在Perfect工程中引入和使用Mustache页面模板与日志记录系统.Mustache页面模板类似于PHP中的smarty模板引擎或者Java中的JSTL标签.当然Mustach ...

  6. 如何有效快速提高Java服务端开发人员的技术水平?

    我相信很多工作了3-5年的开发人员都会经常问自己几个问题: 1.为什么总是感觉技术没有质的提高? 2.如何能够有效和快速的提高自身的技术水平? 3.如何进入到一个牛逼的大公司,认识牛逼的人? 这篇文章 ...

  7. WCF服务端开发和客户端引用小结

    1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...

  8. socket服务端开发之测试使用threading和gevent框架

    socket服务端开发之测试使用threading和gevent框架 话题是测试下多线程和gevent在socket服务端的小包表现能力,测试的方法不太严谨,也没有用event loop + pool ...

  9. 个人公众号服务端开发Demo

    公众号出来很久了,也可以个人申请.知道公众号的服务端开发其实很简单,接口调用封装,数据存取,不外如是. 人一旦懒了,真的是 “无可救药” 了...现简单描述晚到的公众号HelloWorld 思路 公众 ...

随机推荐

  1. 什么是CPA, CPS, CPT?

    在互联网上或移动端进行产品推广时,经常听到很多术语,什么CPA,CPS,CPT等等.不知是怎么来的,今天网上搜一下术语,在这里做一下笔记. CPA(Cost Per Action) 每行动成本. CP ...

  2. wp8.1 Study15:后台任务

    一.介绍 1.多任务处理 什么是多任务处理?它意味着当App被挂起时,它仍然可以完成一些开发者设定的任务,比如更新tiles和toasts.预定toast和提醒.后台任务等. 2.后台任务 App可以 ...

  3. HDU 1402 fft 模板题

    题目就是求一个大数的乘法 这里数字的位数有50000的长度,按平时的乘法方式计算,每一位相乘是要n^2的复杂度的,这肯定不行 我们可以将每一位分解后作为系数,如153 = 1*x^2 + 5*x^1 ...

  4. python leetcode 日记--Maximal Square--221

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ...

  5. Allegro建立引脚封装概念名词梳理

    首先感谢于博士的60讲的Cadence教学视频,老师讲的还是很有耐心,很细致,谢谢! 目前还只是看到建立PCB封装这一块,正好手头上有个案子在做,边做边学的进度还是要好很多.以前的工作对原理图这一块的 ...

  6. php大力力 [042节] 今天做了一个删除功能

    php大力力 [042节] 今天做了一个删除功能 if(isset($_GET['action'])){ if($_GET['action']=="del"){ $sql = &q ...

  7. 关于KNN的python3实现

    关于KNN,有幸看到这篇文章,写的很好,这里就不在赘述.直接贴上代码了,有小的改动.(原来是python2版本的,这里改为python3的,主要就是print) 环境:win7 32bit + spy ...

  8. js便签笔记(3)——切记:appendChild()、insertBefore()是移动element节点!

    appendChild().insertBefore()是移动element节点,看书的时候注意过,也可以做一个简单的例子测试一下: <div id="div1"> & ...

  9. 更新新网卡驱动,修复win7雷凌网卡Ralink RT3290在电脑睡眠时和启动网卡时出现蓝屏netr28x.sys驱动文件错误

    更新新网卡驱动,修复win7雷凌网卡Ralink RT3290在电脑睡眠时和启动网卡时出现蓝屏netr28x.sys驱动文件错误 我的本本是win7,雷凌网卡Ralink RT3290   802.1 ...

  10. Android FM模块学习之四源码学习(2)

    前几章我们分析了FM模块的几个主要的类文件,今天要分析的是:FMTransceiver.java   // 某些工程中名称为FMRadioService.java public class FmTra ...