За последние 24 часа нас посетили 36192 программиста и 1695 роботов. Сейчас ищут 1168 программистов ...

ICQ без переподключений

Тема в разделе "Прочие вопросы по PHP", создана пользователем alexey_baranov, 11 мар 2009.

  1. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    Есть потребность уведомлять пользаков по аське. Есть хороший классец для этих целей. Он работает, но напрягает что при завершении скрипта коннект с Аськой обрывается и в следующий раз нужно занаво переподключаться. Повторные подключения естественно не моментальны и эти задержки очень заметны для пользователей. Как решить эту проблему?
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Делаем скрип-сервер, которому передаём данные (текст сообщения) через сокет. Сам скрипт коннектится к ICQ и в бесконечном цикле слушает сокет, если обнаруживает подключение - принимает данные и рассылает пользователям.
     
  3. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    а попрощее? я же не бил гейтс все- таки
     
  4. admyx

    admyx Активный пользователь

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    А проще - курить мануалы, что такое сокеты, соединения и тд и тп до просветления кармы.
     
  5. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Пример сервера, допускающего подключение к себе нескольких клиентов:
    PHP:
    1. <?php
    2. // Set time limit to indefinite execution
    3.  
    4. // Set the ip and port we will listen on
    5. $address = '127.0.0.1';
    6. $port = 9000;
    7. $max_clients = 10;
    8.  
    9. // Array that will hold client information
    10. $clients = Array();
    11.  
    12. // Create a TCP Stream socket
    13. $sock = socket_create(AF_INET, SOCK_STREAM, 0);
    14. // Bind the socket to an address/port
    15. socket_bind($sock, $address, $port) or die('Could not bind to address: '.$address);
    16. // Start listening for connections
    17. socket_listen($sock);
    18. // Loop continuously
    19. while (true) {
    20.     // Setup clients listen socket for reading
    21.     $read[0] = $sock;
    22.     for ($i = 0; $i < $max_clients; $i++)
    23.     {
    24.         if ($clients[$i]['sock']  != null)
    25.             $read[$i + 1] = $clients[$i]['sock'];
    26.     }
    27.     // Set up a blocking call to socket_select()
    28.     $null=null;
    29.     $ready = socket_select($read,$null,$null,$null);
    30.     /* if a new connection is being made add it to the client array */
    31.     if (in_array($sock, $read)) {
    32.         for ($i = 0; $i <= $max_clients; $i++)
    33.         {
    34.             if ($clients[$i]['sock'] == null) {
    35.                 $clients[$i]['sock'] = socket_accept($sock);
    36.                 break;
    37.             }
    38.             elseif ($i == $max_clients) {
    39.                 socket_close($clients[$i]['sock']);
    40.                 unset($clients[$i]);
    41.                 break;
    42.             }
    43.         }
    44.         if (--$ready <= 0)
    45.             continue;
    46.     } // end if in_array
    47.      
    48.     // If a client is trying to write - handle it now
    49.     for ($i = 0; $i < $max_clients; $i++) // for each client
    50.     {
    51.         if (in_array($clients[$i]['sock'] , $read))
    52.         {
    53.             while ($input .= socket_read($clients[$i]['sock'],128)) {
    54.                 if(substr_count($input,"\r\n")) {
    55.                     $input=str_replace("\r\n",null,$input);
    56.                     break;
    57.                 }
    58.             }
    59.             if ($input == 'Bye!' or $input == null) {
    60.                 // String meaning disconnected
    61.                 unset($clients[$i]);
    62.             }
    63.             elseif ($input == 'exit') {
    64.                 // requested disconnect
    65.                 socket_close($sock);
    66.                 die;
    67.             }
    68.             else {
    69.                 // strip white spaces and write back to user
    70.                 $output = $input."\r\n";
    71.                 socket_write($clients[$i]['sock'],$output);
    72.             }
    73.             $input=null;
    74.         }
    75.         elseif (key_exists($i,$clients)) {
    76.             // Close the socket
    77.             socket_close($clients[$i]['sock']);
    78.             unset($clients[$i]);
    79.         }
    80.     }
    81.     socket_set_block($sock);
    82. } // end while
    83. // Close the master sockets
    84. socket_close($sock);
    85. ?>
    Получая строку Bye или пустую строку, он закрывает соеденение с клиентом, получая строку exit - завершает работу.
    После 18-й строки можешь вставить подключение к ICQ, а в блоке else, который начинается с 69-й строке, рассылку сообщения ($input).
     
  6. alBoo

    alBoo Активный пользователь

    С нами с:
    27 мар 2008
    Сообщения:
    63
    Симпатии:
    0
  7. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    WebIcqPro я знаю. как раз им и пользовался. хороший класец. но как я писал внутри скрипта неудобно его использовать.
    а сокеты на ПХП юзать тяжело. нет хороших классов- оберток. А писать стабильный сокет- сервер таким вот макаром тяжеловато.

    есть же ПХП- шные проекты, которые рассылают асю тоннами. должен значит быть какой- то готовый сервер с админкой и класс для работы с ним из ПХП.

    2 alBoo:
    сколько секунд у тебя выполняется подключение к аське при помощи этого класса?
     
  8. alBoo

    alBoo Активный пользователь

    С нами с:
    27 мар 2008
    Сообщения:
    63
    Симпатии:
    0
    без понятия
    он один раз коннектится и висит демоном, периодически проверяя в БД новые данные для отправки. находит, отправляет, дальше висит пока не убьеш или !stop не напишеш ему
     
  9. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Сокеты на PHP работают очень даже неплохо, если не полениться, то можно очень хорошую систему разработать.
    Есть, они подключаются, рассылают, и отключаются.
     
  10. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    2 alBoo:
    я сразу не понял как он работает. только теперь дошло. то есть команды серверу передаются опять же через асю. это как раз готовый сервер со своеобразной админкой. это очень- очень подходит. просто как все гениальное. спасибо!

    еще бы довести это до такого уровня, считай продукт мирового уровня получится.

    Код (Text):
    1. $sender= new ICQMessageSender($uin, $password, $adminUin, $messageStack);
    2. $sender->start();
    $messageStack - любая реализация fifo стэка, которая в клиентском скрипте кидает новое сообщения в копилку сообщений, а на стороне сендера достает их оттуда. Мне лично нужен постгресовский стэк сообщений, который бы их не удалял после извлечения, кому то из e-mail ящика, кому то из файла или еще как. это уже кому как надо, сам напишет и подключит его к твоему классу.

    нет ли у тебя желания дописать такой вот сендер? будет просто круть

    тогда отправить сообщение из моего скрипта будет всего
    Код (Text):
    1. $messageStack= new PostgresStack();
    2. $messageStack->push(123456, 'hello!');
     
  11. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    2 vs
    да я не говорю что они работают плохо. просто они пока без классов. юзать тяжеловато. будут классы с событиями и исключениями- будем юзать только в путь!

    как тебе идея сендера? две строчки кода и сообщение отправлено. никаких тебе задержек и сокетов. по- моему вариант.
     
  12. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    или вот вариант:
    обернуть твой сокет- сервер в обертку до уровня.
    серве естественно внутри коннектит один раз WebIcqPro
    и написать к такому серверу звонилку типа
    Код (Text):
    1. $message= new ICQMessage($uin, $body);
    2. $message->send();
    а в сенде коннект по сокету к твоему серверу.

    опять же если это все с корректной обработкой всех исключений, переподключения да плюс события на стороне сервера OnConnect(), OnSend($uin, $body) и т.д. тогда тоже вариант. еще какой.

    только здесь один момент. если в первом случае с копилкой сервак не работает или аська не подключается, то задержек в прикладном скрипте не будет. это очень важно. а в твоем случае с сокетами по- моему во время подключения к неработающему серверу опять будут задержки по несколько секунд. или я ошибаюсь?
     
  13. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    WebICQpro это одновременн сокет-сервер и клиент. Разница с моим вариантом лишь в том, что управление им осуществляется с помощью той же icq. Вопрос стоял вначале о постоянн запущенно icq-клиенте, соответственно, ему надо как-то передавать данные в режиме реального времени, а делать это можно только через сокеты, при чем для этого скрипт icq-клиент надо интегрировать с сокет-сервером.
     
  14. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    нет не только через сокеты. можно кидать все сообщения из прикладного скрипта в некую копилку как alBoo
    если проверять копилку даже раз в минуту, получается близко к режиму реального времени, а если уж совсем реалтайм нужен, можно проверять копилку раз в секунду.

    нет ли у тебя желания обернуть твой сервер в простой для использования класс?