Как запустить сокет сервер на сервере

Обновлено: 04.07.2024

Модуль socketserver упрощает задачу написания сетевых серверов.

Существует четыре основных класса серверов:

class socketserver. TCPServer ( server_address, RequestHandlerClass, bind_and_activate=True ) ¶

При этом используется Интернет протокол TCP, который обеспечивает непрерывные потоки данных между клиентом и сервером. Если bind_and_activate истинно, конструктор автоматически пытается вызвать server_bind() и server_activate() . Остальные параметры передаются базовому классу BaseServer .

class socketserver. UDPServer ( server_address, RequestHandlerClass, bind_and_activate=True ) ¶

При этом используются дейтаграммы, которые представляют собой дискретные пакеты информации, которые могут поступать не по порядку или быть потеряны во время передачи. Параметры такие же, как у TCPServer .

class socketserver. UnixStreamServer ( server_address, RequestHandlerClass, bind_and_activate=True ) ¶ class socketserver. UnixDatagramServer ( server_address, RequestHandlerClass, bind_and_activate=True ) ¶

Эти менее часто используемые классы аналогичны классам TCP и UDP, но используют сокеты домена Unix; они недоступны на платформах, отличных от Unix. Параметры такие же, как у TCPServer .

Вышеуказанные четыре класса обрабатывают запросы синхронно; каждый запрос должен завершиться до того, как может стартовать следующий запрос. Это не подходит, если для выполнения каждого запроса требуется много времени, потому что он требует большого объёма вычислений или потому, что он возвращает много данных, которые клиент медленно обрабатывает. Решение состоит в том, чтобы создать отдельный процесс или поток для обработки каждого запроса; классы миксины ForkingMixIn и ThreadingMixIn могут использоваться для поддержки асинхронного поведения.

Создание сервера требует нескольких шагов. Во-первых, вы должны создать класс обработчика запросов, создав подкласс класса BaseRequestHandler и переопределив его метод handle() ; этот метод будет обрабатывать входящие запросы. Во-вторых, вы должны создать экземпляр одного из классов сервера, передав ему адрес сервера и класс обработчика запросов. Рекомендуется использовать сервер в операторе with . Затем вызвать метод handle_request() или serve_forever() серверного объекта для обработки одного или нескольких запросов. Наконец, вызовите server_close() , чтобы закрыть сокет (если вы не использовали оператор with ).

При наследовании от ThreadingMixIn для поведения потокового соединения вы должны явно объявить, как вы хотите, чтобы ваши потоки вели себя при внезапном завершении работы. Класс ThreadingMixIn определяет атрибут daemon_threads, который указывает, должен ли сервер ждать завершения потока. Вы должны явно установить флаг, если хотите, чтобы потоки работали автономно; значение по умолчанию — False , что означает, что Python не завершит работу, пока не завершатся все потоки, созданные ThreadingMixIn .

У классов серверов одни и те же внешние методы и атрибуты, независимо от того, какой сетевой протокол они используют.

Замечания по созданию сервера¶

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

Обратите внимание, что UnixDatagramServer происходит от UDPServer , а не от UnixStreamServer , — единственное различие между IP и потоковым сервером Unix — это семейство адресов, которое просто повторяется в обоих классах серверов Unix.

class socketserver. ForkingMixIn ¶ class socketserver. ThreadingMixIn ¶

С помощью этих миксин классов могут быть созданы форковочные и поточные версии каждого типа сервера. Например, ThreadingUDPServer создаётся следующим образом:

Первым идёт класс миксин, поскольку он переопределяет метод, определенный в UDPServer . Установка различных атрибутов также изменяет поведение базового механизма сервера.

ForkingMixIn и форковочные классы, упомянутые ниже, доступны только на платформах POSIX, которые поддерживают fork() .

socketserver.ForkingMixIn.server_close() ожидает завершения всех дочерних процессов, кроме случаев, когда у атрибута socketserver.ForkingMixIn.block_on_close ложное значение.

socketserver.ThreadingMixIn.server_close() ожидает завершения всех потоков, не являющихся демонами, за исключением случаев, когда у атрибута socketserver.ThreadingMixIn.block_on_close ложное значение. Использовать демонические потоки, задав для ThreadingMixIn.daemon_threads значение True , чтобы не ждать завершения потоков.

Изменено в версии 3.7: socketserver.ForkingMixIn.server_close() и socketserver.ThreadingMixIn.server_close() теперь ожидают завершения всех дочерних процессов и недемонических потоков. Добавлен новый атрибут класса socketserver.ForkingMixIn.block_on_close , чтобы отказаться от поведения до версии 3.7.

class socketserver. ForkingTCPServer ¶ class socketserver. ForkingUDPServer ¶ class socketserver. ThreadingTCPServer ¶ class socketserver. ThreadingUDPServer ¶

Эти классы предварительно определены с помощью миксин классов.

Чтобы реализовать службу, необходимо унаследовать класс от BaseRequestHandler и переопределить его метод handle() . Затем вы можете запускать различные версии службы, объединив один из классов сервера с классом обработчика запросов. Класс обработчика запросов должен быть другим для дейтаграммных или потоковых служб. Это можно скрыть с помощью подклассов обработчиков StreamRequestHandler или DatagramRequestHandler .

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

В некоторых случаях может быть целесообразно обрабатывать часть запроса синхронно, но завершить обработку в форкнутом дочернем в зависимости от данных запроса. Это можно реализовать, используя синхронный сервер и выполняя явный форк в методе класса обработчика запросов handle() .

Другой подход к обработке нескольких одновременных запросов в среде, которая не поддерживает ни потоки, ни fork() (или где они слишком дороги или не подходят для службы), заключается в ведении явной таблицы частично завершённых запросов и использовании selectors , чтобы решить, над каким запросом работать дальше (или нужно ли обрабатывать новый входящий запрос). Это особенно важно для потоковых сервисов, где каждый клиент потенциально может быть подключен в течение длительного времени (если нельзя использовать потоки или подпроцессы). См. другой способ решения этой проблемы в asyncore .

Server объекты¶

class socketserver. BaseServer ( server_address, RequestHandlerClass ) ¶

Это суперкласс всех объектов Server в модуле. Он определяет интерфейс, указанный ниже, но не реализует большинство методов, которые выполняются в подклассах. Эти два параметра хранятся в соответствующих атрибутах server_address и RequestHandlerClass .

Возвращает целочисленный файловый дескриптор для сокета, который прослушивает сервер. Эта функция обычно передаётся selectors , чтобы можно было контролировать несколько серверов в одном процессе.

Обработать единичный запрос. Эта функция вызывает следующие методы по порядку: get_request() , verify_request() и process_request() . Если предоставленный пользователем метод handle() класса обработчика вызывает исключение, будет вызван метод handle_error() сервера. Если в течение timeout секунд запрос не получен, будет вызван handle_timeout() , и вернёт handle_request() .

Обрабатывать запросы до явного запроса shutdown() . Опрос на отключение каждые poll_interval секунд. Игнорирует атрибут timeout . Он также вызывает service_actions() , который может использоваться подклассом или миксином для предоставления действий, специфичных для данного сервиса. Например, класс ForkingMixIn использует service_actions() для очистки дочерних процессов зомби.

Изменено в версии 3.3: Добавлен вызов service_actions к методу serve_forever .

Вызывается в цикле serve_forever() . Этот метод может быть переопределён подклассами или классами миксинов для выполнения действий, специфичных для данной службы, таких как действия по очистке.

Добавлено в версии 3.3.

Сказать циклу serve_forever() остановиться и подождать, пока он не остановится. shutdown() должен вызываться, когда serve_forever() работает в другом потоке, иначе произойдёт взаимоблокировка.

Очистить сервер. Может быть отменено.

Семейство протоколов, к которому принадлежит сокет сервера. Распространенными примерами являются socket.AF_INET и socket.AF_UNIX .

Предоставляемый пользователем класс обработчика запросов; экземпляр этого класса создаётся для каждого запроса.

Адрес, который слушает сервер. Формат адресов зависит от семейства протоколов; подробности см. в документации к модулю socket . Для интернет-протоколов это кортеж, содержащий строку с адресом и целочисленный номер порта: например, ('127.0.0.1', 80) .

Объект сокета, на котором сервер будет прослушивать входящие запросы.

Классы сервера поддерживают следующие переменные класса:

Разрешит ли сервер повторное использование адреса. По умолчанию это False , и его можно установить в подклассах для изменения политики.

Размер очереди запросов. Если обработка одного запроса занимает много времени, поступающие запросы в момент занятости сервера, помещаются в очередь, вплоть до request_queue_size запросов. Как только очередь будет заполнена, дальнейшие запросы от клиентов получат ошибку «В соединении отказано». Значение по умолчанию обычно 5, но это может быть изменено подклассами.

Тип сокета, используемого сервером; socket.SOCK_STREAM и socket.SOCK_DGRAM — два общих значения.

Длительность тайм-аута, измеряемая в секундах, или None , если тайм-аут не требуется. Если handle_request() не получает входящих запросов в течение периода ожидания, вызывается метод handle_timeout() .

Существуют различные методы сервера, которые можно переопределить подклассами базовых классов сервера, например TCPServer ; эти методы бесполезны для внешних пользователей объекта сервера.

finish_request ( request, client_address ) ¶

Фактически обрабатывает запрос, создавая экземпляр RequestHandlerClass и вызывая его метод handle() .

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

handle_error ( request, client_address ) ¶

Эта функция вызывается, если метод handle() экземпляра RequestHandlerClass вызывает исключение. Действие по умолчанию — распечатать трассировку до стандартной ошибки и продолжить обработку запросов.

Изменено в версии 3.6: Теперь вызывается только для исключений, производных от класса Exception .

Эта функция вызывается, когда для атрибута timeout установлено значение, отличное от None , и истек период тайм-аута, а запросы не получены. Действие по умолчанию для форкующих серверов состоит в том, чтобы собрать статус всех дочерних процессов, которые завершились, в то время как на серверах с потоковой передачей этот метод ничего не делает.

process_request ( request, client_address ) ¶

Вызывает finish_request() для создания экземпляра RequestHandlerClass . При желании эта функция может создать новый процесс или поток для обработки запроса; это делают классы ForkingMixIn и ThreadingMixIn .

Вызывается конструктором сервера для активации сервера. Поведение по умолчанию для TCP-сервера просто вызывает listen() в сокете сервера. Может быть отменено.

Вызывается конструктором сервера для привязки сокета к желаемому адресу. Может быть отменено.

verify_request ( request, client_address ) ¶

Должен возвращать логическое значение; если значение True , запрос будет обработан, а если False , запрос будет отклонён. Эту функцию можно переопределить, чтобы реализовать контроль доступа для сервера. Реализация по умолчанию всегда возвращает True .

Изменено в версии 3.6: Добавлена поддержка протокола контекстного менеджера . Выход из менеджера контекста эквивалентен вызову server_close() .

Объекты обработчика запросов¶

Это суперкласс всех объектов обработчика запросов. Он определяет интерфейс, указанный ниже. Конкретный подкласс обработчика запросов должен определять новый метод handle() и может переопределять любой из других методов. Для каждого запроса создаётся новый экземпляр подкласса.

Вызывается перед методом handle() для выполнения любых необходимых действий по инициализации. Реализация по умолчанию ничего не делает.

Эта функция должна выполнять всю работу, необходимую для обслуживания запроса. Реализация по умолчанию ничего не делает. Ему доступны несколько атрибутов экземпляра; запрос доступен как self.request ; адрес клиента self.client_address ; и экземпляр сервера как self.server , если ему нужен доступ к информации о каждом сервере.

Тип self.request отличается для дейтаграмм или потоковых служб. Для потоковых сервисов self.request — объект сокета; для служб дейтаграмм self.request — это пара строки и сокета.

Вызывается после метода handle() для выполнения любых необходимых действий по очистке. Реализация по умолчанию ничего не делает. Если setup() вызывает исключение, эта функция не вызывается.

class socketserver. StreamRequestHandler ¶ class socketserver. DatagramRequestHandler ¶

Этот учебник знакомит с программированием сокетов Java по протоколу TCP/IP с реальным приложением Клиент/сервер.

1. Обзор

Термин сокет программирование относится к написанию программ, которые выполняются на нескольких компьютерах, в которых все устройства подключены друг к другу с помощью сети.

Существует два протокола связи, которые можно использовать для программирования сокетов: Протокол пользовательских дейтаграмм (UDP) и протокол управления передачей (TCP) .

Основное различие между ними заключается в том, что UDP не имеет соединения, что означает отсутствие сеанса между клиентом и сервером, в то время как TCP ориентирован на соединение, что означает, что сначала должно быть установлено исключительное соединение между клиентом и сервером для осуществления связи.

Этот учебник представляет введение в программирование сокетов по сетям TCP/IP и демонстрирует, как писать клиентские/серверные приложения на Java. UDP не является основным протоколом и как таковой может встречаться нечасто.

2. Настройка проекта

Java предоставляет набор классов и интерфейсов, которые заботятся о деталях низкоуровневой связи между клиентом и сервером.

Нам также нужны java.io пакет, который дает нам входные и выходные потоки для записи и чтения во время общения:

3. Простой Пример

Давайте испачкаем руки в самых основных примерах, связанных с клиентом и сервером . Это будет двустороннее коммуникационное приложение, в котором клиент приветствует сервер, а сервер отвечает.

Давайте создадим серверное приложение в классе с именем GreetServer.java со следующим кодом.

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

Давайте также создадим клиент под названием GreetClient.java с этим кодом:

Давайте запустим сервер; в вашей IDE вы делаете это, просто запустив его как Java-приложение.

А теперь давайте отправим приветствие на сервер с помощью модульного теста, который подтверждает, что сервер действительно отправляет приветствие в ответ:

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

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

4. Как Работают Сокеты

Мы будем использовать приведенный выше пример, чтобы пройти через различные части этого раздела.

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

4.1. Сервер

Обычно сервер работает на определенном компьютере в сети и имеет сокет, привязанный к определенному номеру порта. В нашем случае мы используем тот же компьютер, что и клиент, и запустили сервер по порту 6666 :

Сервер просто ждет, слушая сокет, чтобы клиент сделал запрос на подключение. Это происходит на следующем шаге:

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

Если все идет хорошо, сервер принимает соединение. После принятия сервер получает новый сокет clientSocket , привязанный к тому же локальному порту, 6666 , а также имеет свою удаленную конечную точку, установленную на адрес и порт клиента.

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

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

4.2. Клиент

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

Чтобы сделать запрос на подключение, клиент пытается встретиться с сервером на компьютере и порту сервера:

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

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

5. Непрерывная Связь

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

Обратите внимание, что мы добавили условие завершения, при котором цикл while завершается, когда мы получаем символ точки.

Мы запустим Echo Server , используя метод main так же, как мы это сделали для GreetServer . На этот раз мы запускаем его на другом порту, таком как 4444 чтобы избежать путаницы.

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

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

Работа с несколькими клиентами-это другой случай, который мы рассмотрим в следующем разделе.

Давайте создадим метод setup для инициирования соединения с сервером:

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

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

6. Сервер С Несколькими Клиентами

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

Работа с несколькими клиентами-это то, что мы рассмотрим в этом разделе.

Еще одна особенность, которую мы увидим здесь, заключается в том, что один и тот же клиент может отключиться и снова подключиться, не получая исключения отказа в подключении или сброса соединения на сервере. Раньше мы не могли этого сделать.

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

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

Основной поток будет выполнять цикл while, когда он прослушивает новые соединения.

Хватит разговоров, давайте создадим еще один сервер под названием EchoMultiServer.java. Внутри него мы создадим класс потока обработчика для управления коммуникациями каждого клиента в его сокете:

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

Давайте запустим наш сервер, используя его основной метод на порту 5555 .

Для ясности мы все равно поместим тесты в новый набор:

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

7. Заключение

В этом уроке мы сосредоточились на введении в программирование сокетов через TCP/IP и написали простое клиент-серверное приложение на Java.

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

Поддержка браузерами веб-сокетов
Браузер IE Firefox Chrome Safari Opera Safari iOS Android
Минимальная версия 10 6 14 6 12.1 6 -

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

Получение доступа к веб-сокетам

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

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

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

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

Чтобы дать вам представление о масштабе сервера веб-сокетов, рассмотрите некоторые из задач, которые сервер сокетов должен выполнять:

содержать список всех текущих подключенных клиентов;

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

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

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

Простой клиент веб-сокетов

С точки зрения веб-страницы функциональность веб-сокетов легко понять и использовать. Первый шаг — это создать объект WebSocket и передать ему URL. Код для этого подобен следующему:

Строка URL начинается с текста ws://, который идентифицирует подключение типа веб-сокет. Этот URL указывает файл веб-приложения на сервере (в данном случае это сценарий socketServer.php).

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

Если веб-страница решит, что вся ее работа выполнена, она может закрыть подключение, используя метод disconnect():

Примеры веб-сокетов в сети

Если вы заинтересованы опробовать веб-сокеты, в сети есть много сайтов, на которых можно запустить свою разработку.

Сервер веб-сокетов

Хотя этот сервер веб-сокетов и не представляет ничего особенного, на нем вы можете испробовать все возможности объекта WebSocket. Более того, к этому серверу можно подключиться со страницы, расположенной как на промышленном веб-сервере, так и на тестовом веб-сервере на вашем компьютере, или даже со страницы, просто запускаемой с жесткого диска:

Существуют и серверы веб-сокетов, предоставляющие другие возможности, включая следующие:

Многопользовательский альбом. Эта страница объединяет веб-сокеты с HTML5 Canvas. То, что вы рисуете на своем холсте, отображается на холсте других участников, и наоборот. Простой концепт, но очень впечатляющий на практике.

Серверы веб-сокетов

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

Этот простой и слегка сыроватый проект будет хорошей отправной точкой для создания сервера веб-сокетов на PHP.

Существует несколько образцов сервера веб-сокетов на Ruby, но этот, применяющий модель "Event—Machine", пользуется особенной популярностью.

Сервер веб-сокетов в виде модуля расширения для Apache на языке Python.

В зависимости от того, кого вы спросите, система node.JS для разработки веб-приложений на JavaScript — это либо одна из наиболее перспективных платформ, либо просто разросшийся тестовый инструмент.

В отличие от других пунктов этого списка, Kaazing не предоставляет кода для сервера веб-сокетов. Это развитый сервер веб-сокетов, который можно лицензировать для своего веб-сайта. Для разработчиков, которые предпочитают делать все своими руками, он не будет представлять интереса. Но удобно использовать его на менее амбициозных веб-сайтах, особенно принимая во внимание то обстоятельство, что он содержит встроенную поддержку резервных решений в своих клиентских библиотеках (которые сначала пытаются применить стандарт веб-сокетов HTML5, затем Flash, а потом опрос посредством сценариев на JavaScript).

Примечание. Сокеты у нас будут работать, как на серверной части, так и на клиентской. На серверной части этим займется стандартный WebSocket, который появился в HTML5, а работу на серверной части, где у нас PHP будет выполнять библиотека phpws. Есть много подобных библиотек, пожалуй, особенно следует отметить Ratchet, который мне показался громоздким для моего маленького проекта и я остановился на phpws.

Нам нужен Composer

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

Мы его скачали, но команды composer не будут выполняться через PATH, поэтому переместим скачанное в /usr/local/bin

Выполняем команду и получаем результат в виде инструкций и команд Composer, что говорит об удачной установке

Для Windows и Mac можно посмотреть инструкцию на офф-сайте.

Примечание. Все зависимости, которые нужно подключать надо указывать в файле composer.json в корне проекта, который скачает, обновит и соберет все зависимости в одну папку vendor, из которого потом можно загружать через автозагрузчик классов. У Composer есть свое хранилище пакетов и библиотек и называется Packagist, который позволяет указывать vendor/package и он будет установлен. Да, можно указывать конкретные адреса svn/git репозиториев в composer.json, но это неудобно. Намного удобнее иметь какой-то центральный пункт, где есть соответствия пакетов с их адресами репозиториев. Это Packagist.

Нам нужна библиотека phpws

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

В данном случае, мы указали, что скачивать прямо с репозитория GitHub без посредничества Packagist.

Выполним данный файл командой

После чего в папке появится подпапка vendor со скачанными библиотеками и нам остается их подключить и использовать.

Нам нужны базовые понимания работы WebSocket с PHP

И так, на минуточку разберемся, что делать со скачанными библиотеками и как их использовать, углубляться не буду, поэтому, если на пальцах, то нам нужно 2 файла:

Для клиентской части:

Для серверной части:

Стандартный пример вывода текущего времени сервера с обновлением до секунды

Для работы данного примера нужно единожды запустить файл server.php через консоль и после выполнения данного скрипта запуститься сокет-сервер со своим PID

Что делает пример? В примере показано, как до долей секунды сокет обновляет информацию времени на сервер и выдает его клиенту

Стандартный пример простого чата

Показан пример простого чата. Визуально он имеет вид, как на картинке

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

Сначала выводим PID процесса запущенного сокет-сервера. Его мы узнаем посмотрев список запущенных сокетов через их порты через команду:

Находя из списка нужный PID убиваем его через команду:

Читайте также: