Веб-чат в php без использования базы данных или файла - программирование
Подтвердить что ты не робот

Веб-чат в php без использования базы данных или файла

Я пытаюсь реализовать приложение чата реального времени, используя PHP. Возможно ли это сделать, не используя постоянное хранилище данных, такое как база данных или файл. В основном мне нужен медиатор, написанный на PHP, который

  • принимает сообщения из клиентских браузеров
  • Передача сообщения другим клиентам
  • Забывает сообщение
4b9b3361

Ответ 2

Вы должны проверить Web Sockets html5. Он использует двухстороннее соединение, поэтому вам не нужна никакая база данных или файл. Любое сообщение чата, поступающее на сервер, будет напрямую отправлено в другой браузер пользователей без какого-либо вызова Ajax. Но вам также нужно настроить сервер веб-сокетов.

Веб-сокеты также используются во многих приложениях реального времени. Вскоре я планирую написать полный учебник по этому вопросу. Я сообщу вам.

Ответ 3

Просто попробовал что-то, чего я никогда не делал раньше, в ответ на этот вопрос. Казалось, что я работаю, но я только один раз проверил его. Вместо использования Socket у меня возникла идея использования общей переменной Session. В основном я заставил Session_id быть одним и тем же значением независимо от пользователя, поэтому все они используют одни и те же данные. Из быстрого теста это работает. Вот что я сделал:

session_id('12345');
session_start();
$session_id = session_id();
$_SESSION['test'] = $_SESSION['test'] + 1;
echo "session: {$session_id} test: {$_SESSION['test']} <br />";

Итак, мой мыслительный процесс состоял в том, что вы могли просто сохранить информацию о чате в переменной Session и заставить всех, независимо от того, кому они должны использовать общий сеанс. Затем вы можете просто использовать ajax для постоянной перезагрузки текущей переменной сеанса и использовать ajax для редактирования переменной сеанса при добавлении сообщения. Также вы, вероятно, захотите установить, чтобы сессия никогда не заканчивалась или имела действительно длительное максимальное время.

Как я уже сказал, я немного поиграл с этим в течение нескольких минут, чтобы увидеть, будет ли это работать.

Ответ 4

Когда я попытался решить ту же проблему, я пошел с Nginx Push Module. Я решил пойти этим путем, так как мне пришлось поддерживать старые браузеры (которые обычно не поддерживают WebSockets) и не доверяют настройке подходящего решения, такого как Socket.io за прокси-сервером TCP.

Рабочий процесс прошел следующим образом:

  • Клиенты подключаются через длинный опрос к моему местоположению /subscriber, который открыт для всех.
  • Местоположение /publisher принимает только соединения с моего собственного сервера
  • Когда клиент подписывается и разговаривает, он просто просит PHP script обрабатывать любые отправленные данные.
  • Этот script может выполнять проверку, авторизацию и т.д., а затем пересылать (через curl) сообщение в формате JSON в /publisher.
  • Модуль Nginx Push отправляет сообщение обратно подписчикам, а клиент устанавливает новое длинное соединение.

Если бы мне пришлось делать это снова и снова, я бы определенно пошел по пути Socket.io, так как он имеет надлежащие резервные копии для долгого опроса в стиле Comet и имеет отличные документы для сценариев Client и Server.

Надеюсь, что это поможет.

Ответ 5

Вам нужно использовать какое-то хранилище в качестве буфера. Правдоподобно не использовать файл или db (который также использует файл). Вы можете попробовать использовать функции php shared memory, но я не знаю никакого рабочего решения, поэтому вам придется делать это с нуля.

Ответ 6

Можно ли это сделать, не используя постоянное хранилище данных, например базы данных или файла?

Возможно, но вы не должны использовать. База данных или файл не замедляет чат. Он будет предоставлять дополнительную безопасность вашему чат-приложению. Вы можете сделать веб-чат с помощью ajax и сокетов без постоянных данных.

Вы должны увидеть следующие сообщения:

Ответ 7

PHP не подходит для ваших требований (в обычной настройке, такой как apache-php, fastcgi и т.д.), поскольку PHP script выполняется сверху вниз для каждого запроса и не может поддерживать какое-либо состояние между запросами без использования внешних служб или баз данных/файлов (кроме, например, http://php.net/manual/de/book.apc.php, но он не предназначен для реализации чата и не будет масштабироваться несколько серверов.)

Вы должны обязательно посмотреть на Node.js и особенно на модуль Node.js Socket.IO(библиотека Websocket). Он невероятно прост в использовании и скалы. Socket.IO также может масштабироваться до нескольких чат-серверов с дополнительным backis-сервером, что означает, что он легче масштабируется.

Попытка использовать $_SESSION со статическим идентификатором сеанса, поскольку канал связи не является решением, потому что PHP сохраняет данные сеанса в файлах.

Ответ 8

Если у вас есть бизнес-потребность в PHP, то добавление другого языка в смесь означает, что у вас возникнут две проблемы.

Вполне возможно запустить постоянный постоянно работающий демонизированный PHP IRCd-сервер: я знаю, потому что я сделал это, чтобы создать онлайн-игру, которая будет работать годами.

Серверная часть IRC, которую я использовал, является модифицированной версией WaveIRCd: http://sourceforge.net/projects/waveircd/

Я демонизировал его, используя код, который я сделал доступным здесь: http://www.thudgame.com/node/254

Этот код может быть излишним: я написал его настолько надежным, насколько смог, поэтому он пытается демонизировать с помощью PHP pcntl_fork(), затем возвращается к рекурсивному вызову себя в фоновом режиме, затем возвращается к perl и так далее: также обрабатывает ограничения безопасности в безопасном режиме PHP на случай, если кто-то его включит, и ограничения безопасности, налагаемые вызовом через cron.

Возможно, вы могли бы сократить его до нескольких строк: фрагменты с комментариями "Правило демона..." - следуйте этим правилам, и вы просто демонизируете свой процесс.

Чтобы справиться с любой неожиданной смертью демона и т.д., Я затем каждую минуту запускал этого демона через cron, где он проверял, запущен ли демон, и если да, то либо тихо умер, либо демон не отвечал, убивал его и занял свое место.

Из-за всей распределенной природы IRC, он был очень надежным и дал мне многопользовательскую браузерную игру без простоев в течение хороших нескольких лет, пока бит-гниль не съел сайт несколько месяцев назад. Я должен попытаться переписать интерфейс во Flash и снова его восстановить, когда у меня будет время...

(Затем я запустил другой демон-демон для бота PHP для управления самой игрой, затем подключил мою игру к нему в качестве java-апплета и поговорил с ботом, чтобы играть в игру, но это не имеет значения здесь).

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

[2012 edit: там сказано, что если вы хотите, чтобы ваш интерфейс был HTML5/Javascript, или если вы хотите подключиться через тот же порт, через который HTTP соединяется, то ваши параметры более ограничены, чем при использовании Flash или Java. В этом случае воспользуйтесь советом других и используйте "WebSockets" (плохая поддержка в большинстве современных браузеров) или проект "Socket.io" (который использует WebSockets, но использует Flash, или другие различные методы, в зависимости от того, что в браузере есть).

Вышесказанное относится к ситуациям, когда ваш хост позволяет запускать службу на другом порту. В частности, у многих есть явные правила в их ToS против запуска IRCd.]

[2019 edit: WebSockets теперь широко поддерживаются, с ними все должно быть в порядке. Как пример, Slack написан на PHP (per https://slack.engineering/taking-php-seriously-cf7a60065329) и некоторое время поддерживал протокол IRC, хотя я считаю, что с тех пор он был удален. В качестве основного протокола используется API на основе JSON поверх WebSockets (https://api.slack.com/rtm). Все это показывает, что PHP IRCd может обеспечить производительность и качество на уровне предприятия, даже если протокол IRC транслируется в/из другого протокола, что, как вы ожидаете, приведет к снижению производительности.]

Ответ 9

Для этого лучше используйте сервер node.js. В настоящее время WebSockets не являются кросс-браузерами (за исключением socket.io для node.js, который отлично работает)

Ответ 10

в коротком ответе вы не можете. текущая реализация HTTP/HTML не поддерживает pushstate, поэтому алгоритм вашего приложения для чата должен следовать:

  • A: отправленное сообщение
  • B, C, D: делать, пока новое сообщение отправлено, получите это сообщение.

чтобы получатели всегда должны были сделать новый запрос и проверить, было ли отправлено новое сообщение. (Вызов AJAX или что-то подобное) поэтому всегда есть задержка между отправленным событием и событием приема.

  • что означает, что данные должны быть сохранены в чем-то глобальном, например, в db или файловой системе.

найдите: http://today.java.net/article/2010/03/31/html5-server-push-technologies-part-1

Ответ 11

Одним из решений для этого является создание сервера сокетов PHP.

<?php

// Set time limit to indefinite execution

set_time_limit (0);

// Set the ip and port we will listen on

$address = '192.168.0.100';

$port = 9000;

$max_clients = 10;

// Array that will hold client information

$clients = Array();

// Create a TCP Stream socket

$sock = socket_create(AF_INET, SOCK_STREAM, 0);

// Bind the socket to an address/port

socket_bind($sock, $address, $port) or die('Could not bind to address');

// Start listening for connections

socket_listen($sock);

// Loop continuously

while (true) {

    // Setup clients listen socket for reading

    $read[0] = $sock;

    for ($i = 0; $i < $max_clients; $i++)

    {

        if ($client[$i]['sock']  != null)

            $read[$i + 1] = $client[$i]['sock'] ;

    }

    // Set up a blocking call to socket_select()

    $ready = socket_select($read,null,null,null);

    /* if a new connection is being made add it to the client array */

    if (in_array($sock, $read)) {

        for ($i = 0; $i < $max_clients; $i++)

        {

            if ($client[$i]['sock'] == null) {

                $client[$i]['sock'] = socket_accept($sock);

                break;

            }

            elseif ($i == $max_clients - 1)

                print ("too many clients")

        }

        if (--$ready <= 0)

            continue;

    } // end if in_array



    // If a client is trying to write - handle it now

    for ($i = 0; $i < $max_clients; $i++) // for each client

    {

        if (in_array($client[$i]['sock'] , $read))

        {

            $input = socket_read($client[$i]['sock'] , 1024);

            if ($input == null) {

                // Zero length string meaning disconnected

                unset($client[$i]);

            }

            $n = trim($input);

            if ($input == 'exit') {

                // requested disconnect

                socket_close($client[$i]['sock']);

            } elseif ($input) {

                // strip white spaces and write back to user

                $output = ereg_replace("[ \t\n\r]","",$input).chr(0);

                socket_write($client[$i]['sock'],$output);

            }

        } else {

            // Close the socket

            socket_close($client[$i]['sock']);

            unset($client[$i]);

        }

    }

} // end while

// Close the master sockets

socket_close($sock);

?>

Вы выполнили бы это, выполнив его через командную строку и всегда должны запускаться для ваших клиентов PHP для подключения к нему. Затем вы можете написать PHP-клиент, который будет подключаться к сокету.

<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
?>

Вам нужно будет использовать какой-либо тип ajax для вызова с jQuery, отправив сообщение этому клиенту PHP.

http://devzone.zend.com/209/writing-socket-servers-in-php/ http://php.net/manual/en/function.fsockopen.php

Ответ 12

Вы не сказали, что все это должны были быть написаны PHP:)

Установите RabbitMQ, а затем используйте эту реализацию чата, построенную поверх веб-гнезд и RabbitMQ.

Ваш PHP в значительной степени просто "чат-хром". Возможно, большая часть вашего сайта будет вписываться в 5-мегабитный лимит автономного содержимого HTML5, и у вас будет очень гибкая (и, скорее всего, более надежная, чем если бы вы сделали это самостоятельно) чат-систему.

Он даже имеет 20 сообщений истории чата, если вы покидаете комнату.

https://github.com/videlalvaro/rabbitmq-chat

Ответ 13

Если вам нужно использовать только PHP, то вы можете хранить сообщения чата в переменных сеанса, сеанс может быть как объект, хранящий много информации. Если вы можете использовать jQuery, тогда вы можете просто добавить абзац в div после отправки сообщения, но затем, если сайт обновлен, сообщения исчезнут. Или комбинируя, сохраняйте сообщения в сеансе и обновляйте их с помощью jQuery и ajax.

Ответ 14

Попробуйте найти библиотеки сокетов, такие как ZeroMQ, они позволяют мгновенно переносить сообщение и быстрее, чем TCP, и являются в реальном времени. Их инфраструктура позволяет мгновенно передавать данные между точками A и B, без сохранения данных в любом месте (хотя вы все равно можете выбрать). Здесь учебник для клиента чата в ZeroMQ