Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Jabber бот на php - проблема с сокетами (https://forum.antichat.xyz/showthread.php?t=113247)

Krist_ALL 27.03.2009 14:21

Jabber бот на php - проблема с сокетами
 
Всем привет!
Решил написать своего джаббер бота на пхп. Не нада кричать что есть готовые бибоиотеки с xmpp итд, я пишу с нуля. Проблема заключается втом, что функция socket_read читает только один пакет, их бывает приходит 2 или 3, приходится ее писать несколько раз, из-за этого (я так думаю, но не факт что это из-за функции) у меня сбивается порядок огбмена пакеами и соединение рвется что-ли... посылаю данные а ответа не вижу (еслиб я допустил ошибку в формировании данных, пришел бы пакет, говорящий об ошибке в синтаксисе) .. Помогите плз.


PHP код:

<?php 
$JABBER_SERVER 
"jabber.ru"
$PORT 5222
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP); 
if(!
$socket) { echo 'soket open - NO'; exit; } else { echo 'socket open - OK<br>'; }  
 
$connect socket_connect($socket$JABBER_SERVER$PORT);
 if(!
$connect) { echo 'soket connect - NO'; exit; } else { echo 'socket connect - OK<br>'; }  

$t "<stream:stream to='jabber.ru' xmlns='jabber:client' "$t .= "xmlns:stream='http://etherx.jabber.org/streams' xml:lang='ru' version='1.0'/>";
 echo 
'<b>Клиент - </b>'.htmlspecialchars($t).'<br><br>'
socket_write($socket$t); 

$data socket_read($socket5000);
echo 
'<b>Ответ от jabber - </b>'.htmlspecialchars($data)."<br><br>"

$data socket_read($socket5000); 

echo 
'<b>Ответ от jabber - </b>'.htmlspecialchars($data)."<br><br>";  

$data socket_read($socket5000); echo '<b>Ответ от jabber - </b>'.htmlspecialchars($data)."<br><br>";  

$t1 "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5' />"

echo 
'<b>Клиент - </b>'.htmlspecialchars($t1).'<br><br>'

socket_write($socket$t1); $data socket_read($socket5000); 

echo 
'<b>Ответ от jabber - </b>'.htmlspecialchars($data)."<br><br>";    

//socket_close($socket); 

?>


Krist_ALL 27.03.2009 17:01

На многих форумах по пхп мне не помогли. Не знают как сделать...

Вя надежда на вас!

Pashkela 27.03.2009 17:32

попробуй так:

1. $t = блаблабалбала и в конце всегда ."\n";

2. Явно указать длину того, чего пишешь:

socket_write($socket, $t, strlen($t));


3. Читать можно попробовать так:

socket_read($socket, 5000, PHP_NORMAL_READ);


А вообще читай:

http://ru.php.net/socket_read

там есть примеры работы с сокетами, правильные примеры

Krist_ALL 27.03.2009 17:49

Warning: socket_read() [function.socket-read]: unable to read from socket [104]: Connection reset by peer in ....

Сделал как сказал Pashkela но вот такая штука вылезла.....

KaZ@NoVa 27.03.2009 18:26

ты под каким Php этот код писал. У меня ошибку пишет, что функции socket_create не существует.
И я не пойму, что означают строки вида:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5' />

Krist_ALL 27.03.2009 18:34

Плд нормальным! ВОт под каким ты запускаещь скриепт я непойму

laedafess 27.03.2009 19:10

Цитата:

Сообщение от KaZ@NoVa
ты под каким Php этот код писал. У меня ошибку пишет, что функции socket_create не существует.

в пхп надо php_sockets.dll добавить

Gifts 27.03.2009 19:11

Krist_ALL Примерный план подключение к джаббер серверу:

1) Создаем сокет (socket_create)
2) Подключаемся к серверу(socket_connect)
3) Посылаем инициализирующий запрос (<?xml version='1.0'?><stream:stream to=' и т.д.)
4) А вот дальше нужен цикл обработки и собственно ответов. Приблизительного вида:
PHP код:

// $sock - первоначальный сокет от socket_create
while (1)
{
    
$read=array($sock);
    
$count=socket_select($read,$write=null,$exception=null,15);
    
// Если ничего не пришло пропускаем
    // Или если нужно что то послать по собственному желанию - отправляем
    
if ($count<1) continue; 
    
    foreach (
$read as $one)
      {
        
$input=socket_read($one,4096);
        
// Тут обработка принятого пакета
        // например если пришел пакет  stream features ответить пакетом начала SASL авторизации
      
}


Сам сейчас осваиваю питон и тоже пишу свой клиент джаббера

З.Ы. Ох и намучаешься ты с DIGEST-MD5 ))

Pashkela Не вводите людей в заблуждение, если вы не разбираетесь. XMPP не предусматривает символ перевода строк, чтобы можно было читать NORMAL_READ и для socket_write НЕ требуется указывать длину буфера, если конечно не хочется передавать обрезанные данные

Krist_ALL 27.03.2009 19:43

Gifts, сделал я как ты написал, но чет скрипт зависв браузере - полаеися бесконечный цикл же вайл

PHP код:

<?php 
$JABBER_SERVER 
"jabber.ru"
$PORT 5222;  

$socket socket_create(AF_INETSOCK_STREAMSOL_TCP); 

if(!
$socket) { echo 'soket open - NO'; exit; } else { echo 'socket open - OK<br>'; }  

$connect socket_connect($socket$JABBER_SERVER$PORT); 

if(!
$connect) { echo 'soket connect - NO'; exit; } else { echo 'socket connect - OK<br>'; }   

$t "<stream:stream to='jabber.ru' xmlns='jabber:client' "
$t .= "xmlns:stream='http://etherx.jabber.org/streams' xml:lang='ru' version='1.0'/> ";  

echo 
'<b>Клиент - </b>'.htmlspecialchars($t).'<br><br>'

socket_write($socket$t);   



while (
1)  {      


$read=array($socket);      
$count=socket_select($read,$write=null,$exception=  null,15);      
// Если ничего не пришло пропускаем      
// Или если нужно что то послать по собственному желанию - отправляем      

if ($count<1) continue;             
foreach (
$read as $one)     
{        
$input=socket_read($one,4096);          
echo 
"htmlspecialchars($input)";         
// Тут обработка принятого пакета          
// например если пришел пакет  stream features ответить пакетом начала SASL авторизации          //

echo '<b>Ответ от jabber - </b>'.htmlspecialchars($input)."<br><br>";       
}  
}
?>

НА счет типа авторизации - эт канешно сложно, но я выдерну какнить из класса готового.. ПРосто я хочу нааписать своего бота а не готового юзать.

Gifts 27.03.2009 19:48

Krist_ALL Естественно "завис". Клиент принял пакет и в бесконечном цикле ждет, когда придет следующий, а в браузер ничего не выводится из-за буферизации вывода.

Сделай так:
PHP код:

<?php 
$JABBER_SERVER 
"jabber.ru"
$PORT 5222;  
$i=0;

$socket socket_create(AF_INETSOCK_STREAMSOL_TCP); 

if(!
$socket) { echo 'soket open - NO'; exit; } else { echo 'socket open - OK<br>'; }  

$connect socket_connect($socket$JABBER_SERVER$PORT); 

if(!
$connect) { echo 'soket connect - NO'; exit; } else { echo 'socket connect - OK<br>'; }   

$t "<stream:stream to='jabber.ru' xmlns='jabber:client' "
$t .= "xmlns:stream='http://etherx.jabber.org/streams' xml:lang='ru' version='1.0'/> ";  

echo 
'<b>Клиент - </b>'.htmlspecialchars($t).'<br><br>'

socket_write($socket$t);   



while (
1)  {      


$read=array($socket);      
$count=socket_select($read,$write=null,$exceptionnull,1);      
// Если ничего не пришло пропускаем      
// Или если нужно что то послать по собственному желанию - отправляем      
if ($i++ > 5) break; // Соединение оборвется через 5 секунд или 5 принятых пакетов
if ($count<1) continue;             
foreach (
$read as $one)     
{        
$input=socket_read($one,4096);          
echo 
"htmlspecialchars($input)";         
// Тут обработка принятого пакета          
// например если пришел пакет  stream features ответить пакетом начала SASL авторизации          //

echo '<b>Ответ от jabber - </b>'.htmlspecialchars($input)."<br><br>";       
}  
}
?>



Время: 18:17