Php http socket server

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Devristo / phpws Public archive

License

Devristo/phpws

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

⛔️ This project is no longer maintained ⛔️

We urge you to look for a replacement.

WebSocket Server and Client library for PHP. Works with the latest HyBi specifications, as well the older Hixie #76 specification used by older Chrome versions and some Flash fallback solutions.

This project was started to bring more interactive features to http://www.u2start.com/

  • Hixie #76 and Hybi #12 protocol versions
  • Flash client support (also serves XML policy file on the same port)
    • See https://github.com/gimite/web-socket-js for a compatible Flash Client

    The easiest way to set up PHPWS is by using it as Composer dependency. Add the following to your composer.json

    < "repositories": [ < "type": "vcs", "url": "https://github.com/Devristo/phpws" > ], "require": < "devristo/phpws": "dev-master" > >

    And run php composer.phar install

    To verify it is working create a time.php in your project root

    require_once("vendor/autoload.php"); use Devristo\Phpws\Server\WebSocketServer; $loop = \React\EventLoop\Factory::create(); // Create a logger which writes everything to the STDOUT $logger = new \Zend\Log\Logger(); $writer = new Zend\Log\Writer\Stream("php://output"); $logger->addWriter($writer); // Create a WebSocket server using SSL $server = new WebSocketServer("tcp://0.0.0.0:12345", $loop, $logger); $loop->addPeriodicTimer(0.5, function() use($server, $logger)< $time = new DateTime(); $string = $time->format("Y-m-d H:i:s"); $logger->notice("Broadcasting time to all clients: $string"); foreach($server->getConnections() as $client) $client->sendString($string); >); // Bind the server $server->bind(); // Start the event loop $loop->run();

    And a client time.html as follows

    html> head> title>WebSocket TESTtitle> head> body> h1>Server Timeh1> strong id pl-s">time">strong> script> var socket = new WebSocket("ws://localhost:12345/"); socket.onmessage = function(msg)  document.getElementById("time").innerText = msg.data; >; script> body> html>

    Now run the time.php from the command line and open time.html in your browser. You should see the current time, broadcasted by phpws at regular intervals. If this works you might be interested in more complicated servers in the examples folder.

    Getting started with the Phpws Client

    The following is a client for the websocket server hosted at http://echo.websocket.org

    require_once("vendor/autoload.php"); // Composer autoloader $loop = \React\EventLoop\Factory::create(); $logger = new \Zend\Log\Logger(); $writer = new Zend\Log\Writer\Stream("php://output"); $logger->addWriter($writer); $client = new \Devristo\Phpws\Client\WebSocket("ws://echo.websocket.org/?encoding=text", $loop, $logger); $client->on("request", function($headers) use ($logger)< $logger->notice("Request object created!"); >); $client->on("handshake", function() use ($logger) < $logger->notice("Handshake received!"); >); $client->on("connect", function($headers) use ($logger, $client)< $logger->notice("Connected!"); $client->send("Hello world!"); >); $client->on("message", function($message) use ($client, $logger)< $logger->notice("Got message: ".$message->getData()); $client->close(); >); $client->open(); $loop->run();
    • Lacks ORIGIN checking (can be implemented manually in onConnect using getHeaders(), just disconnect the user when you dont like the Origin header)
    • No support for extension data from the HyBi specs.
    • PHP 5.4
    • Open port for the server
    • PHP OpenSSL module to run a server over a encrypted connection
    • http://pecl.php.net/package/pecl_http as its a dependency of Zend\Uri
    • Composer dependencies * These will be installed automatically when using phpws as a composer package.
    • Reactphp
    • ZF2 Logger
    • PHP 5.4
    • Server that implements the HyBi (#8-#12) draft version
    • PHP OpenSSL module to connect using SSL (wss:// uris)

    Источник

    Работа с Веб-сокетами на PHP

    PHP — едва ли первое, что придет в голову, когда стоит задача поднять сервер веб-сокетов. Практически каждая статья в интернете будет пестрить предложениями использовать для этого NodeJS, Python или Go. Но поскольку PHP — это однозначно первое, что приходит в голову, когда речь идет о веб-приложениях, почему бы не попробовать?

    На самом деле, запуск сервера веб-сокетов на PHP довольно прост. Существует превосходная библиотека Ratchet, позволяющая работать на любом фреймворке (или вовсе без него) полноценно и легко.

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

    Авторизация

    По умолчанию, сервер веб-сокетов открыт для любого подключения. Конечно, можно поставить сетевые ограничения по доменам или IP адресам, но для веб-приложения — это, мягко говоря, не эффективный подход. В обычной ситуации мы используем для таких ограничений тот или иной вариант сервиса авторизации — токены, сессии и т.д. Здесь же проблема в том, что мы не сможем отправить через протокол ws:// ни HTTP заголовок, ни cookies. Значительная часть привычных методов, таким образом, не сработает.

    Архитектура

    Основное приложение != сервер веб-сокетов. Для работы с ними всегда необходимо держать в голове, что мы имеем дело с двумя отдельными приложениями, вне зависимости от того, насколько тесно они взаимодействуют между собой. На первый взгляд это может показаться незначительным нюансом, однако такое положение вещей требует особого внимания к подготовке интерфейсов для интеграции основного приложения и сервера веб-сокетов. Ко всему прочему, это порождает еще одну проблему.

    База данных

    Поскольку сервер веб-сокетов — это отдельное от основного бэкенда приложение, он ничего не знает о существующей базе данных. Сложно представить себе современное приложение на PHP, написанное без использование какого-либо фреймворка и ORM, так что перед разработчиком встанет дополнительная задача интегрировать службы, сервисы и библиотеки для работы с БД в сторонний скрипт.

    Решения

    Для каждой из названных проблем вполне возможно отыскать соответствующее решение. Некоторые из потенциальных решений могут показаться шероховатыми, но главное, что они рабочие.

    Авторизуем пользователей

    В процессе подключения к серверу веб-сокетов существует этап, на котором исходный HTTP запрос преобразуется в WS запрос. Используемая нами библиотека Ratchet сохраняет этот начальный запрос в объекте Connection. Хотя возможности подцепить Bearer заголовок к запросу нет (для клиентского приложения запрос строится сразу как ws://websocket-server), мы можем передать токен (например, JWT) в параметрах запроса. При использовании HTTPS — это вполне безопасный способ передачи.

    В итоге, запрос на подключение может выглядеть примерно так:

    Строку параметров затем можно извлечь из упомянутого ранее объекта Connection.

    После извлечения токен может использоваться в любом уже применяющемся механизме авторизации, реализованном в основном приложении.

    Интегрируем базу данных

    В 9 из 10 случаев основное приложение будет написано на одном из популярных фреймворков вроде Laravel или Symfony. Все, что нам необходимо реализовать в такой ситуации — внедрение службы, отвечающей за ORM, в конструктор сервера веб-сокетов. При условии, что для запуска сервера используется консольная команда, использующая компонент Symfony Console, мы можем сделать это в два этапа: первоначальной инъекцией в конструктор консольной команды, а оттуда передачей в конструктор основного класса веб-сокетов.

    Разделяем приложения

    Раз уж мы вынуждены расценивать основное приложение и сервер веб-сокетов как два отдельных компонента, ничто не мешает нам использовать API основного приложения внутри сервера веб-сокетов. Пожалуй, самый распространенный сценарий — сохранение сообщений в БД и последующая отдача их фронтенд-приложению.

    В целом, после внедрения ORM в обработчик веб-сокетов, мы могли бы выполнять все это с помощью обычных CRUD-операций. Но гораздо более эффективным решением было бы использовать уже готовый API. Почему? Во-первых, это позволит избежать дублирования кода (ровно такие же CRUDы используются в контроллерах, отвечающих за API). Во-вторых, таким способом мы укладываемся в общую архитектуру разделенных компонентов, даже внутри монолитного решения. Более того, имея одновременно токен из исходного запроса и внедренный ORM, мы получаем возможность авторизовывать действия и валидировать данные при абсолютно каждом событии веб-сокетов, а это уже полноценная имперсонификация пользователя.

    Выводы

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

    Источник

    Читайте также:  Как скомпилировать питон программу
Оцените статью