чат на сокетах php

Simple PHP Chat using WebSocket

In this tutorial, we are going to create a simple chat application using WebSocket and PHP socket programming. The WebSocket is used to create a bridge to send or receive messages from the PHP chat server.

In the web world, we generally use HTTP request methods to communicate between the client and server side. In this chat example, we use sockets to communicate with the server.

For establishing a socket connection between the client and the server, we use the WebSocket protocol (ws://) to specify the address of the PHP page where the WebSocket handshake is handled.

After creating WebSocket there are callbacks to handle the events that occur between the client and the server during the chat process.

Creating WebSocket and Callback Event Handlers

The following script is used to create WebSocket in client side and define callback handlers to handle the different chat events. These handlers give acknowledgments about the connection state, chat messages and the errors if any.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

The chat message is encoded in JSON format and sent to the server on submit.

The encoded data will be decoded in the PHP endpoint to create the chatbox message instance. Apart from the JSON encode decode, PHP supports heavily to handle JSON data programmatically to read write parse and more.

PHP Socket Programming for the Chat Application

This PHP code checks for the new socket connection request. If any of a new connection request is found, then it will accept and perform the handshake with the new socket resource.

Then, it sends an acknowledgment to the client about the connectivity by sealing the encoded acknowledgment message.

It receives the socket data sent via the existing connections and unseals and decodes it to bundle the received data and send it to the chat client. The handshake, seal, unseal, send functionalities are handled by using the ChatHandler class.

and the chat handler class is

Establish Connection using Command Line

The following image shows the command line screen to establish the connection to start chatting by using this application.

Источник

petukhovsky.com

Чуть более недели назад мне удалось разработать неплохое экономичное решение webockets демоны на PHP хостинге которое может работать на хостинге за 2 доллара в месяц. Оно не требует доступа консоли, оно не требует библиотеки работы с сигналами и форками. И даже удалось сделать панель управления, позволяющую управлять демоном из браузера. И это большой успех, т.к. до этого я считал что вменяемая работа с сокетами невозможна на дешевом хостинге. Еще несколькими неделями раньше я писал о том, что такое веб-сокеты и с чего начать при работе с этой технологией. Настало время для написания полноценных простых приложений. Сегодня я разработаю простейший чат, как это обычно делают все кто начинает работать с этой технологией.

Т.к. в моём распоряжении обычный PC под управлением ОС Windows и для разработки чата на ws, мне всё же понадобится система управления процессом под windows (под *nix то же самое только правильнее называть демоном). Возьму за основу описанную в прошлой статье панель управления (Downloads, ws server admin panel pre-alpha) и модифицирую её для работы под ОС Windows с установленным Денвером.

Вначале приведу результат работы.

Анонимный ролевой флейм-чат

Далее о том, как это было разработано.

Фоновый процесс из PHP в ОС Windows

Решение оказалось не однозначным — изначально везде где нужно была добавлена проверка версии ОС на которой запущен PHP скрипт, и в зависимости от ОС следовало выполнение команды запуска ws сервера (демона).

Всё заработало. Обратите внимание, что пришлось переименовать проект и все файлы, т.к. сейчас разрабатывается проект не echo сервера, а более общий случай — ws сервер. Ради интереса проверил перечень программ которые появляются в диспетчере задач Windows. Оказалось целых три программы:

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

И это логично: консоль для исполнения команд, php интерпретатор, и окно консоли узла (правда, не совсем понимаю что это).

В процессе я опасался того, что под ОС Windows всё будет сложнее и запасся готовыми решениями и советами с php.net. Спешил уже написать о том, какое простое решение оказалось и что эти советы не понадобились. Однако, по непонятным причинам через несколько дней предложенное выше решение начало зависать при выполнении команды exec в PHP скрипте запуска.
И одним из советов с php.net воспользоваться всё таки пришлось.

В результате код запуска выглядит следующим образом.

Примечательно то, что в диспетчере задач теперь появляется только одна дополнительная строка — php.exe.

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

If you try to use the psexec from Sysinternals on your Windows Server for background-processes that need special user-rights and get an “Access denied” oder “Wrong user or password” notice, although your username and password is right, this could help you getting around this bug.

Хотя, уверен что в 90% случаев права администратора не понадобятся.

ws сервер + панель управления улучшенная

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

Features

Бонусом идёт ws echo клиент и ws чат клиент, которые шлют AJAX запросы включающие ws сервер, перед попыткой каждого соединения по протоколу ws. Не забывайте править конфиг: данные авторизации, порты и команду запуска ws в ОС Windows, которая требует указания точного пути к файлу ws.php.

В ОС Windows медленно работает запуск и завершение работы (до 7 секунд), так что наберитесь терпения. Я проверял работу в ОС Windows 7 под Денвером.

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

ws приложение чат

Теперь, когда все инструменты готовы, можно заняться и творческими вещами, например, написанием простенького чата на ws. Код сервера пришлось значительно переписать и вы это увидите скачав архив ws сервера предложенный несколькими абзацами выше. Причиной для такой переработки послужила не реализация логики чата, которая очень проста, а приведение кода в порядок и необходимость реализации устойчивой работы под ОС Windows.

Фактически, ws сервер чата такой же echo сервер, за исключением того, что он отправляет сообщение всем подключенным ws клиентам. А как мы знаем — у нас есть метод вызываемый при получении сообщения от пользователя в который и нужно добавить код рассылки сообщений всем пользователям.

Борьба с утечками памяти

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

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

upd 2016.09.15: Долго ломал голову над проблемой – почему не работает exec на *nix после перезагрузки сервера пока не залогинюсь по ssh. Ответ прост: php нужно запускать из-под root пользователя.

Источник

Делаем вебсокеты на PHP с нуля

Некоторое время назад я выбирал библиотеку для работы с вебсокетами. На просторах интернета я натыкался на статьи по интеграции node.js с yii, а почти все статьи о вебсокетах на хабре ограничивались инструкциями к тому, как использовать phpdaemon.

Я изучал библиотеки phpdaemon и ratchet, они достаточно монструозны (причём используя ratchet для отправки сообщения конкретному пользователю рекомендовано дополнительно использовать wamp). Мне не совсем было понятно для чего использовать таких монстров, которые требуют установку других монстров. Почитав исходники этих, а также других библиотек, я разобрался как всё устроено и мне захотелось написать простой вебсокет-сервер на php самостоятельно. Это помогло мне закрепить изученный материал и наткнуться на некоторые подводные камни, о которых я не имел представления.

Так я решил написать необходимый для меня функционал с нуля.

Получившийся код и ссылка на демонстрационный чат в конце статьи.

Поставленные цели:

1) разобраться с серверными сокетами в php
2) разобраться с протоколом вебсокетов
3) написать с нуля простой сервер вебсокетов

1) Серверные сокеты в php

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

используя расширение php «socket»:

или используя расширение php «stream»:

Я предпочёл второй вариант ввиду его краткости.

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

или с использованием stream_select

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

2) Протокол вебсокетов

«Рукопожатие» или handshake:

Считываем значение Sec-WebSocket-Key из пришедшего заголовка от клиента, рассчитываем на его основе Sec-WebSocket-Accept и отправляем итоговый ответ:

обмен сообщениями

Простой сервер вебсокетов

Итак, у нас есть вся необходимая информация.
Используя код простого http сервера из первой части, а также функции handshake, decode и encode из второй мы можем собрать простой сервер вебсокетов.

В приведённом примере можно менять пользовательские сценарии onOpen, onClose и onMessage для реализации необходимого функционала.

Поставленные цели достигнуты.
Если этот материал вам покажется интересным, то в следующей статье я опишу как можно запускать несколько процессов для обработки соединений (один мастер и несколько воркеров), межпроцессное взаимодействие, интеграцию с вашим фреймворком на примере компонента yii.

Источник

Как применять вебсокеты js в связке с php?

Хочу написать простенький чат на сокетах js. В js это реализовано на стандарте RFC 6455, открытие сокета производится следующей строчкой:

Еще не понятно как это всё обрабатывать на стороне сервера (php), все примеры которые я встречал были на node.js, а что с php, подскажите?

2 ответа 2

Ты можешь создать сокет соединение на php, код ниже. Далее ты попросту обрабатываешь все сообщения которые приходят. В браузере на js уже подключаешься к 127.0.0.1:8000.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

В первую очередь нужно понять что сокет соеденение состоит из двух частей.
1.Сокет клиент который подключает к определенному порту (скажем 8080)
2. Сокет сервер который слушает определенный порт (8080) и если ему обратился сокетКлиент то создается соединение.

В js нужно естественно писать точный адресс. Обязательно указовать порт потому что сокет сидит только в канкретном порту. т.е. адрес выглядит как то так «192.168.1.1:8080». Это пример подключения к конкретному 8080 порту. Можно указать любой порт. Желательно редкий. Если порт будет занят то сокет не заработает. что насчет Реализации на пхп. Если честно на пхп сокет не серьезно. Именна изза сокета я в свое время перешол на Ява для веб и не пожелел. Но думаю если захотеть то можно найти примеры. Если не ошибаюсь я видел какойто готовый фреймворк толи библиотеку на пхп для реализации чата с помощью сокета. RedChat кажется точно не помню. Если вы не пишите серьезный чат то можно возпользоваться но если хотите серьезное программу которая работала без отказна то переходи на что нибудь по серьезней. Я сделал выбор в сторону Java. Выбор большой от c# до python.
Ну и еще если вы новичек (а вы скорее всего новичек) То оссобенность сокета в том что простой запрос проходит по схеме запрос->ответ->соединение разрывается то сокет просто соеденяется и не разрывает соеденение пока один из них не захочит выйти. Сокет соединяется и нужно там в бесконечно цикле выводить данные. при каждой итерации js будит ловить отправленные тобой данные и делать че надо. Сокет на пхп мне лично показался геморойным когда я хотел ее изучить. Я нашел хороший пример от Михаила Русакова. Вбей в гугл там в топах найдешь. Хороший робочий пример.
Удачи в освоении программирования 😉

Источник

Чат на WebSocket’ах

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

В статье описывается, как разработать и запустить простейший чат на вебсокетах.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Сервер

Существует много готовых продуктов для запуска websocket-сервера. Наш сервер мы запустим используя библиотеку Workerman, ключевое преимущество которой – это полное отсутствие зависимостей: скачал, запустил – работает. Также в Workerman имеется поддержка таймеров прямо из коробки, они нам пригодятся. И конечно же! Библиотека написана на PHP, а все любят PHP 😉

Клиент

Для разработки приложения-клиента я выбрал фреймворк Qt только потому, что он мне нравится. Qt – кроссплатформенная библиотека (фреймворк), позволяющая создавать программы практически под любую платформу: Windows, Linux, Android, OS X, iOS и др. Разумеется, клиент для полученного сервера можно написать на чем угодно, хоть на HTML+JS, который будет работать прямо из браузера.

1. Настройка VDS-сервера

Сразу после приобретения VDS и установки операционной системы (выбрал свежую версию Ubuntu 18.04 на тарифе «Master») подключаемся к нему. На сервер можно зайти через консоль из панели управления VDS, но это не самый удобный вариант. Предпочтительнее подключаться по SSH.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Если разные способы подключения по SSH из Windows, например:
1. Воспользоваться программой Putty;
2. Воспользоваться терминалом Cygwin;
3. Воспользоваться терминалом Ubuntu из WSL (я выбрал этот способ).

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

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

где – это IP-адрес вашего сервера, который можно найти в панели управления VDS (блок «Список используемых IP-адресов»).

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Установка Workerman

Чтобы скачать Workerman, сначала устанавливаем composer:

Теперь скачиваем Workerman в папку /usr/local/workerman:

И создаём php-файл, в котором будем писать код сервера чата:

Если работаете в Linux, то из рабочего окружения KDE можно подключиться через файловый менеджер Dolphin по протоколу SFTP и открыть файл в любом редакторе или даже в IDE (например, в KDevelop).

Если работаете в Windows, то можете скачать Notepad++ с плагином NppFTP, либо что-то более продвинутое, вроде Sublime / Atom / Visual Studio Code, и так же подключиться по протоколу SFTP.

2. Сервер

Чат будет работать по такому принципу: сообщения между сервером и клиентом передаются в формате JSON с указанием, какое «действие» (action) выполняет это сообщение. Таким образом можно разделить сообщения на типы: служебные, публичные, приватные и т.д., и с лёгкостью дополнять различные типы служебной и иной сопутствующей информацией.

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

Наш простейший чат будет поддерживать следующие действия:

action = Authorized
При подключении пользователя к чату сервер предварительно проверяет свободность выбранного никнейма. Если никнейм занят, то приписываем к нему номер (2, 3, 4 и т.д.). Если никнейм свободен, то отправляем пользователю сообщение «Authorized», в котором передаются данные, с которыми он был авторизован в чате и список пользователей чата.
Дополнительно пользователь может выбрать цвет отображения своего имени и указать, к какому полу (М/Ж) относится.

action = Connected
После авторизации нового пользователя сервер отправляет всем участникам сообщение «Connected», в котором передаются данные авторизованного пользователя.

action = Disconnected
При выходе пользователя из чата все участники оповещаются сообщением «Disconnected».

action = PublicMessage
Если пользователь отправляет сообщение в чат без указания адресата, то такое сообщение определяется как «Публичное» и рассылается всем участникам.

action = PrivateMessage
Если пользователь отправляет сообщение в чат с указанием адресата, то такое сообщение определяется как «Приватное» и отправляется только адресату.

action = Ping
Сервер рассылает всем участникам служебное сообщение «Ping» с определённым интервалом и ожидает от каждого ответное сообщение «Pong».

action = ConnectionLost
Если сервером несколько раз подряд не будет получено ответное на «Ping» сообщение от участника, то участник считается отключившимся, всем остальным участникам рассылается сообщение «ConnectionLost» с данными “отвалившегося” пользователя.

Инициализация WebSocket-сервера

И это всё. При запуске этого php-скрипта WebSocket-сервер будет запущен на порту 27800 и к нему уже можно будет подключиться.

Но обратите внимание: можно указать любой другой свободный порт, главное не забыть открыть его на VDS-сервере командой:

где – выбранный вами порт для чата.

Запускаем WebSocket-сервер командой:

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Для проверки соединения и дальнейшей отладки можно воспользоваться плагином Simple WebSocket Client для браузера Google Chrome.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Окно плагина Simple WebSocket Client

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

Инициализировать сервер было легко, но надо ведь ещё обработать события!

Подключение и авторизация пользователя

Авторизация пользователя будет происходить во время подключения клиента к серверу с передачей параметров. Параметры подключения передаются в адресной строке как в обычном URL-адресе (QUERY STRING), а на сервере их можно прочитать из переменной $_GET.

Предполагается, что при подключении приложение-клиент должно передать все необходимые сведения о пользователе:
— отображаемое имя (ник): параметр userName;
— цвет ника: параметр userColor;
— пол: параметр gender.

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

При подключении клиента к websocket-серверу, вызывается функция Worker::onConnect, в которую передается указатель на созданный объект соединения TcpConnection.

Обратите внимание!

Вызов функцииWorker::runAll() запускает цепь обработки событий Workerman. Код, написанный после вызова этой функции, не будет выполнен. Помните об этом при внесении дальнейших изменений.

Сохраним файл на сервере и перезапустим Workerman. Остановить предыдущий запуск можно клавишами CTRL+C, а затем снова запустить той же командой:

Обратите внимание!

Перезапускать WebSocket-сервер нужно после каждого внесения изменений в любой из php-скриптов вашего проекта.

Пробуем подключиться с передачей параметров: ws://:27800?userName=anonymous

И вот, наконец, мы добрались до Hello World!

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

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

Сохраняем файл, перезапускаем сервер, переподключаемся к вебсокету и видим получение двух сообщений:

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Первое (Authorized) отправляется только подключившемуся пользователю, чтобы сообщить ему, с какими данными он был подключен.

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

Отключение пользователя

Когда клиент закрывает соединение с сервером, вызывается функция Worker::onClose, тут обработаем выход пользователя из чата:

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

Пинг пользователей

При вызове метода Worker::runAll запускаются все объявленные «работники» (их может быть несколько), а при их запуске вызывается функция Worker::onWorkerStart – здесь добавим код таймера для пинга пользователей.

Примечание

Протокол WebSocket имеет встроенную реализацию ping/pong из коробки, но мы напишем собственную, в которой сможем выполнять дополнительные действия. Однако клиент будет дополнительно оповещать сервер о наличии подключения, используя встроенную реализацию.

Обработка сообщений

На этом с сервером закончили. Полный код файла ChatWorker.php доступен на GitHub: https://github.com/wxmaper/SimpleChat-server

После тестирования websocket-сервер можно запустить в режиме службы, для этого нужно добавить параметр -d:

Перезапуск выполняется командой restart:

3. Клиент

Примитивное приложение-клиент будет реализовано с использованием модуля QtWidgets и написано на C++. Сообщения будут отображаться в обычном текстовом поле в режиме readonly (привет любителям лампового IRC :-)).

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

Режим приватного чата активируется двойным кликом по имени в списке пользователей, а закрывается этот режим специальной кнопкой [x], которая по умолчанию скрыта.

Сообщения отправляются нажатием на кнопку Return (Enter) на клавиатуре.

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

Прототип окна чата

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

чат на сокетах php. Смотреть фото чат на сокетах php. Смотреть картинку чат на сокетах php. Картинка про чат на сокетах php. Фото чат на сокетах php

В рамках этой статьи рассмотрим лишь основные моменты.

Установка соединения с сервером

Если же ввести все авторизационные данные, то будет осуществлена попытка подключения к серверу.

Обработка сообщений

Вся логика общения клиента с сервером реализована в слоте Widget::onTextMessageReceived – тут проверяется тип входящего сообщения (какое он имеет «действие») и вызываются соответствующие методы для его обработки.

Оповещение пользователя

Если кликнуть по имени пользователя, то имя вставляется в поле ввода сообщения и заворачивается в фигурные скобки: «<» и «>».

На сервере имеется паттерн обработки такого текста (функция $worker->onMessage), который заменяет фигурные скобки на теги « » и « », выделяя текст жирным шрифтом.

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

По такой же схеме можно реализовать полноценную поддержку markdown, вставку смайликов и картинок.

Расширяя функционал сервера и клиента можно также добавить:

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *