ejabberd服务端开发笔记
2016-05-27 10:50
369 查看
网上一搜一大陀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
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.ymlejabberd configuration fileejabberdctl.cfgConfiguration file of the administration scriptinetrcNetwork DNS configuration file/lib/ejabberd/ebin/Erlang binary files (*.beam)include/Erlang header files (*.hrl)priv/Additional files required at runtimebin/Executable programslib/Binary system libraries (*.so)msgs/Translation files (*.msgs)/sbin/ejabberdctlAdministration script (see section 4.1)/share/doc/ejabberd/Documentation of ejabberd/var/lib/ejabberd/Spool directory:.erlang.cookieErlang 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.logejabberd service logerlang.logErlang/OTP system log
6.
接下来需要使用客户端进行简单的测试,网上搜了一下,选择了smack。
首先写一个注册功能:
[java] view plain copy
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
[plain] view plain copy
{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,再次运行注册代码,发现依然失败。然后改为使用如下代码,注册成功:
[java] view plain copy
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:
[plain] view plain copy
{captcha_protected, true}
[java] view plain copy
%%%. =======
%%%' 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响应如下:
[html] view plain copy
<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>
验证码图片为
[html] view plain copy
http://192.168.17.102:5280/captcha/2824232941/image
Over!
控制台输出:
vi /sbin/ejabberdctl
[html] view plain copy
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
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.ymlejabberd configuration fileejabberdctl.cfgConfiguration file of the administration scriptinetrcNetwork DNS configuration file/lib/ejabberd/ebin/Erlang binary files (*.beam)include/Erlang header files (*.hrl)priv/Additional files required at runtimebin/Executable programslib/Binary system libraries (*.so)msgs/Translation files (*.msgs)/sbin/ejabberdctlAdministration script (see section 4.1)/share/doc/ejabberd/Documentation of ejabberd/var/lib/ejabberd/Spool directory:.erlang.cookieErlang 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.logejabberd service logerlang.logErlang/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
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
[plain] view plain copy
{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,再次运行注册代码,发现依然失败。然后改为使用如下代码,注册成功:
[java] view plain copy
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:
[plain] view plain copy
{captcha_protected, true}
[java] view plain copy
%%%. =======
%%%' 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响应如下:
[html] view plain copy
<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>
验证码图片为
[html] view plain copy
http://192.168.17.102:5280/captcha/2824232941/image
Over!
控制台输出:
vi /sbin/ejabberdctl
[html] view plain copy
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
相关文章推荐
- 课堂水王2
- 一步步学spark之一scala高级特性中隐式转换,隐式参数,隐式类3.8
- 设置各个浏览器的兼容问题的代码
- C++的lambda表达式
- .Tostring("")
- leetcode---Maximum Subarray---动态规划
- Android中shape的使用
- cortex 内核简介
- Androin学习笔记五十四: android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果
- 环信即时通讯在工程中的安装——Nusen_Liu
- HTTP协议学习篇
- ConcurrentHashMap源码分析
- JFinal 3分钟入门(续)
- crosswalk-webview
- css特殊字符总结
- jswing中为dialog设置透明窗体
- hdu 3440(差分约束)
- 教你快速写出多线程Junit单元测试用例 - GroboUtils
- mongodb性能调试基本技巧
- 三次样条曲线