За последние 24 часа нас посетили 51014 программистов и 1754 робота. Сейчас ищут 959 программистов ...

создание чата. работа с сокетами

Тема в разделе "Прочие вопросы по PHP", создана пользователем kelod, 19 ноя 2011.

  1. kelod

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

    С нами с:
    26 апр 2011
    Сообщения:
    32
    Симпатии:
    0
    проблемма не совсем даже с сокетами, данные отправляються и получаються отлично (тьху тьху тьху что бы не сглазить) проблема в том, как на сервере узнавать что данные пришли , пробывал писать простой демон с бесконечным циклом, если клиентов нет, то он вещает проц капитально, плюс его коннект и постоянные запросы к базе , это ужас какой-то. перечитал пол интернета ничего путного так и не нащёл(( так что вот сижу не знаю как и быть что делать((
     
  2. Михаил

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

    С нами с:
    12 июл 2009
    Сообщения:
    545
    Симпатии:
    0
    Адрес:
    Bielarus
    какая база у вас? может стоит использовать редис какой-нибудь?
     
  3. iliavlad

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

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    вот есть уже с чего начать. давайте код, посмотрим)
     
  4. kelod

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

    С нами с:
    26 апр 2011
    Сообщения:
    32
    Симпатии:
    0
    вообщем перекопал пол нета, перечитал кучу умных книжек, вот что получилось в конце концов

    <?php
    error_reporting(E_ALL);
    set_time_limit(0);
    ob_implicit_flush();

    function __autoload ($className)
    {
    $fileName = "Classes/".str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
    $status = (@include_once $fileName);

    if ($status === false) {
    eval(sprintf('class %s {func' . 'tion __construct(){throw new Project_Exception_AutoLoad("%s");}}', $className, $className));
    }
    }

    $ip = '127.0.0.1';
    $port = 9999;

    //new SocketServer($ip, $port);

    try{
    $mySocketServer = new SocketServer($ip, $port);
    } catch (Project_Exception_AutoLoad $e) {
    echo "FATAL ERROR: CAN'T FIND SOCKET SERVER CLASS.";
    }

    ?>

    и собственно сам класс

    <?php
    class SocketServer
    {
    var $ip;
    var $port;

    var $games;

    var $masterSocket;

    var $logger;

    private $currentSockets;

    function __construct($ip, $port)
    {
    $this->ip = $ip;
    $this->port = $port;

    $this->games = array();

    $this->logger = Logger::getInstance();

    $this->initSocket();
    $this->currentSockets = array();

    $this->currentSockets[] = $this->masterSocket;

    $this->listenToSockets();
    }

    private function initSocket()
    {
    //Создать сокет

    if (($this->masterSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0)
    {
    $this->logger->log("[SocketServer] "."socket_create() failed, reason: " . socket_strerror($this->masterSocket));
    }

    socket_set_option($this->masterSocket, SOL_SOCKET,SO_REUSEADDR, 1);

    if (($ret = socket_bind($this->masterSocket, $this->ip, $this->port)) < 0) {

    $this->logger->log("[SocketServer] "."socket_bind() failed, reason: " . socket_strerror($ret));

    }


    if (($ret = socket_listen($this->masterSocket, 5)) < 0) {

    $this->logger->log("[SocketServer] "."socket_listen() failed, reason: " . socket_strerror($ret));
    }
    }

    public function sendMessage($sockets, $message)
    {
    $message .= "\0";

    if(!is_array($sockets))
    $sockets = array($sockets);

    foreach($sockets as $socket)
    {
    if($socket === NULL)
    continue;

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

    $this->logger->log("[SocketServer] Wrote : ".$message." to ".$socket);

    }
    }

    private function parseRequest($socket, $data)
    {

    $this->sendMessage($socket, '000'.$data.'jklgkj');

    try
    {
    //echo '0'.$data.'0';

    //$this->sendMessage($socket, '000'.$data.'jklgkj');


    //$this->sendMessage($socket, $data);
    }
    catch(Exception $e)
    {
    $this->logger->log("[SocketServer] Exception: ".$e->getMessage());
    }
    }

    private function removePlayerFromGame($socket)
    {
    foreach($this->games as $k=>$game)
    {
    //Проверка на число человек в игре (если никого нет удаляем игру)
    if($game->removePlayer($socket))
    {
    if(count($game->players) == 0)
    {
    unset($this->games[$k]);
    $this->logger->log("[SocketServer] Last Player In Game Has Left, Removing Game.");
    }
    break;
    }
    }

    }


    private function listenToSockets()
    {

    //Бесконечный цикл для обработки приходящих данных
    while (true) {

    $changed_sockets = $this->currentSockets;

    //Дальше код не выполняется пока нет изменений в каком-нибудь из сокетов
    $num_changed_sockets = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL);

    foreach($changed_sockets as $socket)
    {
    if ($socket == $this->masterSocket) {
    if (($client = socket_accept($this->masterSocket)) < 0) {
    $this->logger->log("[SocketServer] "."socket_accept() failed: reason: " . socket_strerror($socket));
    continue;
    } else {

    // Присоеденился новый пользователь
    $this->currentSockets[] = $client;
    socket_getpeername($client, $newClientAddress);
    $this->logger->log("[SocketServer] "."NEW CLIENT ".$client." [IP: ".$newClientAddress."]");
    }
    } else {
    $bytes = socket_recv($socket, $buffer, 4096, 0);

    if ($bytes == 0) {

    // Пользователь отсоеденился
    $this->logger->log("[SocketServer] "."REMOVING CLIENT ".$socket ."");
    $index = array_search($socket, $this->currentSockets);

    // Удаляем его сокет
    unset($this->currentSockets[$index]);

    $this->removePlayerFromGame($socket);

    socket_close($socket);

    }else{

    //Клиент что-то послал

    $this->parseRequest($socket, $buffer);


    //$this->sendMessage($socket, '000jklgkj');

    //$this->sendMessage($socket, $buffer);

    //$this->"[SocketServer] Exception: ";
    $this->logger->log("ver ");
    }
    }
    }

    }
    }

    }
    ?>

    вс вроде нормально, но не передаются данные от клиента, клиенту пересылаються, хотя с кодировкой что то , но это мелочи, пробывал писать простой цикл, без обьектов и проверок всяких, данные прихотят, а сюда не как
     
  5. kelod

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

    С нами с:
    26 апр 2011
    Сообщения:
    32
    Симпатии:
    0
    как я понимаю не работает функция socket_recv($socket, $buffer, 4096, 0); верней она работает, но в переменную $buffer ничего не заноситься, пробывал сипользовать socket_read, но с ней вообще не фурычит почему-то((( помогите чем нибудь