ejabberd服务端开发笔记

这篇笔记详细记录了ejabberd服务端的安装配置过程,包括遇到的erl_driver.h缺失的问题及解决方案。此外,还介绍了如何使用xmpp protocal,以及通过smack客户端进行注册功能的实现,并探讨了ejabberd模块测试的方法,特别是验证码的获取设置。ejabberd的相关参考资料稀缺,这篇笔记为开发者提供了实用的帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


首先写一个注册功能: 

	public boolean register(String username, String password) {
		try {
			ConnectionConfiguration config = new ConnectionConfiguration(
					"192.168.17.102", 5222);
			connection = new XMPPConnection(config);
			connection.connect();
			System.out.println("connect ok, user,pass:" + username + " "
					+ password);
			AccountManager am = connection.getAccountManager();
			am.createAccount(username, password);
			connection.disconnect();
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
		

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

 {mod_register, [
                  %%
                  %% Protect In-Band account registrations with CAPTCHA.
                  %%
                  {captcha_protected, true},

                  %%
                  %% Set the minimum informational entropy for passwords.
                  %%
                  %%{password_strength, 32},

                  %%
                  %% After successful registration, the user receives
                  %% a message with this subject and body.
                  %%
                  {welcome_message, {"Welcome!",
                                     "Hi.\nWelcome to this XMPP server."}},

                  %%
                  %% When a user registers, send a notification to
                  %% these XMPP accounts.
                  %%
                  %%{registration_watchers, ["admin1@example.org"]},

                  %%
                  %% Only clients in the server machine can register accounts
                  %%
                  {ip_access, [{allow, "127.0.0.0/8"},
                               {deny, "0.0.0.0/0"}]},

                  %%
                  %% Local c2s or remote s2s users cannot register accounts
                  %%
                  %%{access_from, deny},
                  {access, register}
                 ]},

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

	public void register2(String username, String password, String email,
			String fullName) {
		try {
			ConnectionConfiguration config = new ConnectionConfiguration(
					"192.168.17.102", 5222);
			connection = new XMPPConnection(config);
			connection.connect();

			Registration reg = new Registration();
			reg.setType(IQ.Type.SET);
			reg.setTo(connection.getServiceName());
			// attributes.put("username", username);
			// attributes.put("password", password);
			// reg.setAttributes(attributes);
			Map<String, String> attr = new HashMap<String, String>();
			attr.put("username", username);
			attr.put("password", password);
			attr.put("email", email);
			attr.put("name", fullName);
			reg.setAttributes(attr);

			PacketFilter filter = new AndFilter(new PacketIDFilter(
					reg.getPacketID()), new PacketTypeFilter(IQ.class));
			PacketCollector collector = connection
					.createPacketCollector(filter);
			connection.sendPacket(reg);

			IQ result = (IQ) collector.nextResult(SmackConfiguration
					.getPacketReplyTimeout());
			// Stop queuing results
			collector.cancel();// 停止请求results(是否成功的结果)
			if (result == null) {
				System.out
						.println("xmppMainRegiter”, “No response from server.");
			} else if (result.getType() == IQ.Type.ERROR) {
				if (result.getError().toString()
						.equalsIgnoreCase("conflict(409)")) {
					System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "
							+ result.getError().toString());
					System.out.println("conflict");
				} else {
					System.out.println("xmppMainRegiter" + " IQ.Type.ERROR: "
							+ result.getError().toString());
					System.out.println("注册失败");
				}
			} else if (result.getType() == IQ.Type.RESULT) {
				System.out.println("注册成功");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}


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

{captcha_protected, true}

%%%.   =======
%%%'   CAPTCHA

%%
%% Full path to a script that generates the image.
%%
{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.

%%
%% Host for the URL and port where ejabberd listens for CAPTCHA requests.
%%
{captcha_host, "192.168.17.102:5280"}.

%%
%% Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
%%
{captcha_limit, 5}.

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

<iq id="hLfY6-0" from="192.168.17.102" type="result">
  <query xmlns="jabber:iq:register">
    <instructions>You need a client that supports x:data and CAPTCHA to register</instructions>
    <x xmlns="jabber:x:data" type="form">
      <instructions>Choose a username and password to register with this server</instructions>
      <field var="FORM_TYPE" type="hidden">
        <value>urn:xmpp:captcha</value>
      </field>
      <field label="User" var="username" type="text-single">
        <required/>
      </field>
      <field label="Password" var="password" type="text-private">
        <required/>
      </field>
      <field type="fixed">
        <value>If you don't see the CAPTCHA image here, visit the web page.</value>
      </field>
      <field var="captchahidden" type="hidden">
        <value>workaround-for-psi</value>
      </field>
      <field label="CAPTCHA web page" var="url" type="text-single">
        <value>http://192.168.17.102:5280/captcha/2824232941/image</value>
      </field>
      <field var="from" type="hidden">
        <value>192.168.17.102</value>
      </field>
      <field var="challenge" type="hidden">
        <value>2824232941</value>
      </field>
      <field var="sid" type="hidden">
        <value>hLfY6-0</value>
      </field>
      <field label="Enter the text you see" var="ocr">
        <required/>
      </field>
    </x>
    <data xmlns="urn:xmpp:bob"/>
  </query>
</iq>

验证码图片为
http://192.168.17.102:5280/captcha/2824232941/image

Over!


控制台输出:

 vi /sbin/ejabberdctl

start ()
{
    checknodenameusage
    [ "$?" -eq 0 ] && echo "\nERROR: The node '$ERLANG_NODE' is already running." && return 1

    $EXEC_CMD "$ERL \
      $NAME $ERLANG_NODE \
      -noinput -detached \
      -pa $EJABBERD_EBIN_PATH \
      -mnesia dir \"\\\"$SPOOLDIR\\\"\" \
      $KERNEL_OPTS \
      -s ejabberd \
      -sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
      $ERLANG_OPTS $ARGS \"$@\""
}
去掉-noinput -detached


Over!




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值