XMPP相關(guān)資料:https://blog.csdn.net/nassue_sn/article/category/6635474
Ejabberd相關(guān)資料:https://blog.csdn.net/nassue_sn/article/category/6601126
群聊離線消息實現(xiàn):http://www.cnblogs.com/lovechengcheng/p/4083398.html
簡單集群搭建:https://blog.csdn.net/yongche_shi/article/details/52956125
C#連接ejabberd2.1.x —— agsxmpp
注冊新賬戶方法:(偽碼)
XmppClientConnection xmppCon;
xmppCon.RegisterAccount = true; // 設(shè)為true代表是新用戶注冊
xmppCon.OnRegistered += (sender) => {
// 新用戶注冊成功
};
xmppCon.OnRegisterError += (sender, e) => {
// 老用戶重復(fù)注冊
};
xmppCon.Open();
----------------------------------------- 下方內(nèi)容因版本不匹配暫時廢棄 --------------------------------------------------
PHP通過xmlrpc注冊ejabberd用戶
http://www.bubuko.com/infodetail-551255.html
正在研發(fā)一款社交軟件,架構(gòu)im使用了ejabberd作為xmpp服務(wù)器,于是遇到了如何通過php注冊xmpp用戶的問題。
解決方法有幾個:
1.用xmpphp框架發(fā)送含<body>元數(shù)據(jù)的消息到服務(wù)器要求處理,這個可參考:http://blog.csdn.net/newjueqi/article/details/7864066
//1、測試文件 adduser.php
include_once './XMPPHP/XMPP.php';
$conn = new XMPPHP_XMPP($host, 5222, $xmppUserName, $xmppPassword, 'xmpphp', 'svn.zhaoduila.net', false);
try {
$conn->connect();
//發(fā)送好友請求、發(fā)送消息、刪除好友 需要以下兩行
$conn->processUntil('session_start');
$conn->presence();
//添加用戶
// $conn->registerNewUser($xmppUserName, $xmppPassword, $email);
//發(fā)送消息
// $conn->message('liuruikang1@svn.zhaoduila.net', 'This is a test message!');
//發(fā)送好友請求
// $conn->addRosterContact($jid, $name);
//刪除好友
$conn->deleteRosterContact($jid);
$conn->disconnect();
} catch (XMPPHP_Exception $e) {
die($e->getMessage());
}
//2、我是直接把方法追加到 XMPP.php 文件中的
/**
* Register a new user.
*
* @param $entity
* Entity we want information about
*/
public function registerNewUser($username, $password = NULL, $email){
if (!isset($password))
$password = $this->genRandomString(15);
$id = 'reg_' . $this->getID();
$xml = "<iq type='set' id='$id'>
<query xmlns='jabber:iq:register'>
<username>" . $username . "</username>
<password>" . $password . "</password>
<email>" . $mail . "</email>
<name></name>
</query>
</iq>";
$this->addIdHandler($id, 'register_new_user_handler');
$this->send($xml);
}
/**
* Handler for new user registration
*
* @param XML Object $xml
*/
public function register_new_user_handler($xml){
//dpm($xml);
//var_dump($xml);
switch ($xml->attrs['type']) {
case 'error':
$this->event('new_user_registered', 'error');
break;
case 'result':
// dpm($xml->subs);
$query = $xml->sub('query');
$username='';
$password='';
if(!is_array($query->subs)) {
foreach ($query->sub as $key => $value) {
switch ($value->name) {
case 'username':
$username = $value->data;
break;
case 'password':
$password = $value->data;
break;
}
}
}
$this->event('new_user_registered', array('jid' => $username . "@{$this->server}", 'password' => $password));
default:
$this->event('new_user_registered', 'default');
}
}
/**
* Add contact to your roster
*/
public function addRosterContact($jid, $name, $groups = array()){
// return if there is no jid specified
if(!$jid) return;
// set name to the jid if none is specified
if (!$name) { $name = $jid; }
$id = $this->getID();
$xml = "<iq type='set' id='$id'>";
$xml .= "<query xmlns='jabber:iq:roster'>";
$xml .= "<item jid='$jid' name='$name'>";
foreach ($groups as $group) {
$xml .= "<group>$group</group>";
}
$xml .= "</item>";
$xml .= "</query>";
$xml .= "</iq>";
$xml .= "<presence to='" . $jid . "' type='subscribe'/>";
$this->addIdHandler($id, 'add_roster_contact_handler');
$this->send($xml);
}
/**
* @param XML Object $xml
*/
protected function add_roster_contact_handler($xml) {
// do anything you wish here
$this->event('contact_added');
}
/**
*
* @param $jid
* Contact you wish to remove
*/
public function deleteRosterContact($jid) {
$id = $this->getID();
$xml = "<iq type='set' id='$id'>";
$xml .= "<query xmlns='jabber:iq:roster'>";
$xml .= "<item jid='" . $jid . "' subscription='remove' />";
$xml .= "</query>";
$xml .= "</iq>";
$this->addIdHandler($id, 'delete_roster_contact_handler');
$this->send($xml);
}
/**
*
* @param XML Object $xml
*/
protected function delete_roster_contact_handler($xml) {
// do any handling you wish here
$this->event('contact_removed');
}
function genRandomString($length){
$str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$len=strlen($str)-1;
$randstr='';
for($i=0;$i<$length;$i++){
$num=mt_rand(0,$len);
$randstr .= $str[$num];
}
return $randstr;
}
include_once './XMPPHP/XMPP.php';
$conn = new XMPPHP_XMPP($host, 5222, $xmppUserName, $xmppPassword, 'xmpphp', 'svn.zhaoduila.net', false);
try {
$conn->connect();
//發(fā)送好友請求、發(fā)送消息、刪除好友 需要以下兩行
$conn->processUntil('session_start');
$conn->presence();
//添加用戶
// $conn->registerNewUser($xmppUserName, $xmppPassword, $email);
//發(fā)送消息
// $conn->message('liuruikang1@svn.zhaoduila.net', 'This is a test message!');
//發(fā)送好友請求
// $conn->addRosterContact($jid, $name);
//刪除好友
$conn->deleteRosterContact($jid);
$conn->disconnect();
} catch (XMPPHP_Exception $e) {
die($e->getMessage());
}
//2、我是直接把方法追加到 XMPP.php 文件中的
/**
* Register a new user.
*
* @param $entity
* Entity we want information about
*/
public function registerNewUser($username, $password = NULL, $email){
if (!isset($password))
$password = $this->genRandomString(15);
$id = 'reg_' . $this->getID();
$xml = "<iq type='set' id='$id'>
<query xmlns='jabber:iq:register'>
<username>" . $username . "</username>
<password>" . $password . "</password>
<email>" . $mail . "</email>
<name></name>
</query>
</iq>";
$this->addIdHandler($id, 'register_new_user_handler');
$this->send($xml);
}
/**
* Handler for new user registration
*
* @param XML Object $xml
*/
public function register_new_user_handler($xml){
//dpm($xml);
//var_dump($xml);
switch ($xml->attrs['type']) {
case 'error':
$this->event('new_user_registered', 'error');
break;
case 'result':
// dpm($xml->subs);
$query = $xml->sub('query');
$username='';
$password='';
if(!is_array($query->subs)) {
foreach ($query->sub as $key => $value) {
switch ($value->name) {
case 'username':
$username = $value->data;
break;
case 'password':
$password = $value->data;
break;
}
}
}
$this->event('new_user_registered', array('jid' => $username . "@{$this->server}", 'password' => $password));
default:
$this->event('new_user_registered', 'default');
}
}
/**
* Add contact to your roster
*/
public function addRosterContact($jid, $name, $groups = array()){
// return if there is no jid specified
if(!$jid) return;
// set name to the jid if none is specified
if (!$name) { $name = $jid; }
$id = $this->getID();
$xml = "<iq type='set' id='$id'>";
$xml .= "<query xmlns='jabber:iq:roster'>";
$xml .= "<item jid='$jid' name='$name'>";
foreach ($groups as $group) {
$xml .= "<group>$group</group>";
}
$xml .= "</item>";
$xml .= "</query>";
$xml .= "</iq>";
$xml .= "<presence to='" . $jid . "' type='subscribe'/>";
$this->addIdHandler($id, 'add_roster_contact_handler');
$this->send($xml);
}
/**
* @param XML Object $xml
*/
protected function add_roster_contact_handler($xml) {
// do anything you wish here
$this->event('contact_added');
}
/**
*
* @param $jid
* Contact you wish to remove
*/
public function deleteRosterContact($jid) {
$id = $this->getID();
$xml = "<iq type='set' id='$id'>";
$xml .= "<query xmlns='jabber:iq:roster'>";
$xml .= "<item jid='" . $jid . "' subscription='remove' />";
$xml .= "</query>";
$xml .= "</iq>";
$this->addIdHandler($id, 'delete_roster_contact_handler');
$this->send($xml);
}
/**
*
* @param XML Object $xml
*/
protected function delete_roster_contact_handler($xml) {
// do any handling you wish here
$this->event('contact_removed');
}
function genRandomString($length){
$str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$len=strlen($str)-1;
$randstr='';
for($i=0;$i<$length;$i++){
$num=mt_rand(0,$len);
$randstr .= $str[$num];
}
return $randstr;
}
2.使用php的xmpp庫jaxl,其demo代碼中包含一個register_user的腳本,通過shell調(diào)用:
php example/register_user.php YOUR_DOMAIN
即可生成用戶,缺點是性能較差且慢,不建議
3.最優(yōu)方法是使用ejabberd自帶的命令行工具ejabberdctl來直接生成用戶。網(wǎng)上的回答基本是通過修改sudo用戶組權(quán)限來直接在php使用exec語句來執(zhí)行此命令
$username = ‘tester‘;
$password = ‘testerspassword‘;
$node = ‘myserver.com‘;
exec(‘sudo /usr/sbin/ejabberdctl register ‘.$username.‘ ‘.$node.‘ ‘.$password.‘ 2>&1‘,$output,$status);
if($output == 0)
{
// Success!
}
else
{
// Failure, $output has the details
echo ‘<pre>‘;
foreach($output as $o)
{
echo $o."\n";
}
echo ‘</pre>‘;
}
$password = ‘testerspassword‘;
$node = ‘myserver.com‘;
exec(‘sudo /usr/sbin/ejabberdctl register ‘.$username.‘ ‘.$node.‘ ‘.$password.‘ 2>&1‘,$output,$status);
if($output == 0)
{
// Success!
}
else
{
// Failure, $output has the details
echo ‘<pre>‘;
foreach($output as $o)
{
echo $o."\n";
}
echo ‘</pre>‘;
}
需要在sudoer文件中添加ejabberd用戶權(quán)限,相對不安全也比較麻煩,也不推薦。
4.其實ejabberd在最近的版本中已經(jīng)集成了xmlrpc模塊,通過該模塊可直接訪問4560端口使用ejabberd的一些內(nèi)部命令。官網(wǎng)介紹地址:https://www.ejabberd.im/ejabberd_xmlrpc
修改ejabberd.yml配置文件:
重啟后 telnet HOST地址 4560 看能否接通,即說明xmlrpc已經(jīng)可以用了:
listen:
-
port: 4560
ip: "::"
module: ejabberd_xmlrpc
access_commands:
xmlrpc_access:
commands: all
options: []
..
commands_admin_access: xmlrpc_access
..
access_rules:
xmlrpc_access:
- allow: xmlrpc_acl
..
api_permissions:
"console commands":
from:
- ejabberd_ctl
who: all
what: "*"
"admin access":
who:
- access:
- allow:
- acl: loopback
- acl: all
- oauth:
- scope: "ejabberd:admin"
- access:
- allow:
- acl: loopback
- acl: all
-
port: 4560
ip: "::"
module: ejabberd_xmlrpc
access_commands:
xmlrpc_access:
commands: all
options: []

commands_admin_access: xmlrpc_access

access_rules:
xmlrpc_access:
- allow: xmlrpc_acl

api_permissions:
"console commands":
from:
- ejabberd_ctl
who: all
what: "*"
"admin access":
who:
- access:
- allow:
- acl: loopback
- acl: all
- oauth:
- scope: "ejabberd:admin"
- access:
- allow:
- acl: loopback
- acl: all
重啟后 telnet HOST地址 4560 看能否接通,即說明xmlrpc已經(jīng)可以用了:
關(guān)于php端的代碼在介紹地址中已有提及,以下是php通過ejabberdctl注冊一個用戶的demo的代碼:
$params=array('user'=>'someUser','host'=>'ejabberdHost','password'=>'somPassword');
$request = xmlrpc_encode_request('register', $params, (array('encoding' => 'utf-8')));
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "User-Agent: XMLRPC::Client mod_xmlrpc\r\n" .
"Content-Type: text/xml\r\n" .
"Content-Length: ".strlen($request),
'content' => $request
)));
$file = file_get_contents("http://127.0.0.1:4560", false, $context);
$response = xmlrpc_decode($file);
if (xmlrpc_is_fault($response)) {
trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
} else {
print_r($response);
}
$request = xmlrpc_encode_request('register', $params, (array('encoding' => 'utf-8')));
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "User-Agent: XMLRPC::Client mod_xmlrpc\r\n" .
"Content-Type: text/xml\r\n" .
"Content-Length: ".strlen($request),
'content' => $request
)));
$file = file_get_contents("http://127.0.0.1:4560", false, $context);
$response = xmlrpc_decode($file);
if (xmlrpc_is_fault($response)) {
trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
} else {
print_r($response);
}
打印后即生成注冊成功的結(jié)果
Have a nice try! :)
Linux安裝php-xmlrpc擴(kuò)展:
Linux安裝php-xmlrpc擴(kuò)展:
cd php-5.4.16/ext/xmlrpc
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-xmlrpc=shared --with-libxmlrpc=/usr/local
make
make install
添加到php.ini擴(kuò)展即可
更多參考:
添加到php.ini擴(kuò)展即可
更多參考:
https://github.com/processone/ejabberd/issues/1231
https://github.com/processone/ejabberd/issues/1749
https://github.com/processone/ejabberd/issues/1568
https://bugs.php.net/bug.php?id=19124
https://www.ejabberd.im/ejabberd_xmlrpc/
https://blog.csdn.net/kenkao/article/details/53333595
https://blog.csdn.net/u012930316/article/details/55251903
https://www.cnblogs.com/--00/p/erlang_into_style.html