клиент серверное приложение php

Сокеты: Клиент на PHP

клиент серверное приложение php

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

Привожу код клиента на PHP:

Код хорошо прокомментирован, поэтому, думаю, что здесь всё предельно понятно. Алгоритм работы клиента тривиальный: создание сокета, подключение к серверу, отправка запросов, получение ответов, закрытие соединения. Мы с Вами отправили число 15. Если Вы читали предыдущую статью, то помните, что задача сервера это число возвести в квадрат и вернуть его. Поэтому если Вы запустите этот клиент, то увидите от сервера 225 (15*15). Потом мы подаём команду shutdown, которая останавливает сервер.

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

клиент серверное приложение php

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

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

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Комментарии ( 9 ):

Михаил,здравствуйте.Я никогда не имел дел с сокетом,с чего лучше начинать?Мне нужно чтобы скрипт вытаскивал инфу с игрового сервера и выводил в понятном мне формате.Что посоветуйте? вот пример. http://narod.ru/disk/61234356001.1422047c71b5cae33ed0f7a891da12b5/inv.php.html

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

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

Вроде все сделал правильно! Если в браузере отткрыт фаил «server.php» то все срабатывает нормально, но только один раз. Что можно сделать? Я вроде все установил как надо

Михаил, Здравствуйте. Я сохранил код сервера и код клиента, затем открыл вкладку в браузере через которую запустил код сервера, а потом запустил код клиента и все работает замечательно, но почему-то всего лишь один раз, если запустить код клиента еще один раз, то лезут ошибки «socket_connect(): unable to connect [10061]: No connection could be made because the target machine actively refused it.» Пробовал не закрывать соединение как на сервере так и на клиенте, код не работает, а точнее лезут опять же ошибки. Как запустить сервер так, чтобы я мог в любое время обращаться к нему? Если обращаться к серверу через HTML5 websocket нужно ли серверу отправлять заголовки о том, что он поддерживает сокеты? И в какой части кода они должны отправляться? Заранее очень благодарен за ответы!

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

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

Copyright © 2010-2021 Русаков Михаил Юрьевич. Все права защищены.

Источник

Клиент-серверная работа с табличными данными для начинающих

Вместо начала.

Недавно пришлось заняться написанием приложения по работе. Раньше работал исключительно с PHP и web-мордами, однако быо требование сделать полноценное windows-приложение с авторизацией, использованием forms и прочей «петрушки». Эту статью я пишу на отвлеченном абстрактном примере с целью сделать ман доступным и простым. Собственно, здесь важен сам ход действий, нежели само приложение.

Задача была без веб-интерфейса работать с табличными данными, получаемыми с сервера. Доступные инструменты: web-сервер Apache + PHP + MySQL и C#-приложение на стороне клиента.

Профессионалам вряд ли будет интересно. А вот новичкам, мне кажется, может пригодиться. Очень надеюсь, что я не перемудрил с воплощением идеи.
Кому интересна реализация связки — прошу под кат.

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

Клиент, напомню, пишется на языке C#. От WPF пришлось отказаться, т. к. в нашей конторе больше жалуют стандартный вариант с Windows Forms. Серверная часть создавалась на PHP, ибо это просто оказалось быстрее, чем писать полноценный CGI-клиент под Mono Complete, хотя в будущем планируется отказываться от «пыхи» PHP в пользу писанного на C# демона.

Хочу сказать, что это мой первый опыт работы с VisualStudio (использую VS2013 c ReSharper) и C#. Потому если где-то можно было сделать удобнее, не судите строго — с удовольствием почитаю комментарии и учту в дальнейших своих разработках.

Шифрование данных

За основу взят формат Base-64 из-за своей универсальности на различных платформах.

Запрос к серверу

Для работы потребуется библиотека «Newtonsoft.Json«. Добавьте ее в References проекта, иначе не будет работать. Сразу хочу отметить, что сервер работает под управлением Debian Squeeze и везде используется кодировка UTF-8. Потому в коде предусмотрены строки для совместимости. Никому не хочется кракозябр в гуе. Комментировать такой код по ходу не вижу смысла — он очевиден.

Теперь перейдем к основной теме статьи.
Давайте рассмотрим на примере бесполезной таблицы контактов.

Поля (заголовки столбцов) таблицы пусть будут следующими:

Для начала опишу часть на PHP (серверная сторона).

В общих чертах. Здесь мы подключаемся к базе данных, получаем нужные данные (используется PDO) и формируем ответ в виде массива. Если записи отсутствуют, возвращаем сообщение об ошибке.

Массив с данными имеет формат:

Array[
0 => array[«Id» => «значение», «Title» => «значение», «PhoneNumber» => «значение», «Email» => «значение», «Messengers» => «значение»],
1 => array[«Id» => «значение», «Title» => «значение», «PhoneNumber» => «значение», «Email» => «значение», «Messengers» => «значение»],

N => array[«Id» => «значение», «Title» => «значение», «PhoneNumber» => «значение», «Email» => «значение», «Messengers» => «значение»]
]

В дальнейшем считаю такую форму наиболее удобной для работы с базами данных и наборами двумерных данных вида «ключ — значение».

Обмен данных происходит по протоколу HTTP, потому достаточно обычного вывода «на экран» полученных данных и завершения работы скрипта.
Значение каждого поля кодируется в Base-64 формат, а весь массив данных преобразуется в JSON-формат и снова кодируется в Base-64. Достаточно безопасно и удобно для разбора в клиентской части приложения.

Теперь разберем сторону клиента.

Я использовал сочетание компонентов dataSet и dataGridView.

На форме есть два (для начала) компонента: dataSetContactsTable, dataGridViewContactsTable.

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

При добавлении компонента dataSet я выбрал вариант «Нетипизированный набор данных».
Теперь настроим компонент dataSet. В свойствах я установил ему:

Жмем кнопочку «Добавить» и настраиваем созданную таблицу. Вот те параметры, которые я установил:

Колонки таблицы должны соответствовать прилетающим с сервера данным. Потому, было сделано так:

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

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

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

Все поля таблицы, кроме ID записи, должны отображаться пользователю приложения. Потому поле Id — единственное, у которого установлен параметр «Visible» в значение «False». В остальном настройки похожи.

Всё. Работа мышкой завершена, теперь можно перейти к коду.

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

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

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

По аналогичному принципу можно построить любое другое табличное приложение. Вроде, всё. Надеюсь, что ничего не забыл описать и что материал описан достаточно доступно и просто.

Источник

Делаем вебсокеты на 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.

Источник

Клиент серверное приложение php

В первых трёх уроках, по многочисленным просьбам форумчан, мы рассмотрим создание сокет клиента/сервера на packal, as 3.0, php. Уроки – НЕ ДЛЯ НАЧИНАЮЩИХ, почитайте сначала книги по данным языкам программированиям, ознакомьтесь с общим функционалом.

Вспомогательные материалы:
Справочник по сокетам на as 3.0
Справочник по сокетам на php

Что нам потребуется:

Любой локальный хостинг – Xampp, Denwer, Open Server, Appserv, Nginx.
PSPad – программа для написания php скриптов можно и другие.
Компилятор для pascal – любой.
Компилятор для as 3.0 – любой, я использую adobe flash cs5.

Введение:

клиент серверное приложение php
Сокеты (англ. socket — углубление, гнездо, разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.
Следует различать клиентские и серверные сокеты. Клиентские сокеты грубо можно сравнить с оконечными аппаратами телефонной сети, а серверные — с коммутаторами. Клиентское приложение (например, браузер) использует только клиентские сокеты, а серверное (например, веб-сервер, которому браузер посылает запросы) — как клиентские, так и серверные сокеты.
Интерфейс сокетов впервые появился в BSD Unix. Программный интерфейс сокетов описан в стандарте POSIX.1 и в той или иной мере поддерживается всеми современными операционными системами.
Принципы сокетов: каждый процесс может создать слушающий сокет (серверный сокет) и привязать его к какому-нибудь порту операционной системы (в UNIX непривилегированные процессы не могут использовать порты меньше 1024). Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. При этом сохраняется возможность проверить наличие соединений на данный момент, установить тайм-аут для операции и т.д. Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если привязать сокет к UNIX-адресу, то будет создан специальный файл (файл сокета) по заданному пути, через который смогут сообщаться любые локальные процессы путём чтения/записи из него (см. Доменный сокет Unix). Сокеты типа INET доступны из сети и требуют выделения номера порта.
Обычно клиент явно подсоединяется к слушателю, после чего любое чтение или запись через его файловый дескриптор будут передавать данные между ним и сервером.

Состояние Описание
open программа-сервер готова принимать подключения

listen
filtred файрвол или иная причина не позволяет nmap’у определить открыт или зарыт порт
closed

Источник

Пишем SOAP клиент-серверное приложение на PHP

Всем привет!
Так случилось, что в последнее время я стал заниматься разработкой веб-сервисов. Но сегодня топик не обо мне, а о том, как нам написать свой XML Web Service основанный на протоколе SOAP 1.2.

1 Постановка задачи

1.1 Границы

В начале предлагаю разобраться с тем результатом, которого мы достигнем в конце топика. Как было объявлено выше, мы будем писать сервис по отправке sms-сообщений, а если еще точнее, то к нам будут поступать сообщения из разных источников по протоколу SOAP. После чего, мы рассматрим в каком виде они приходят на сервер. Сам процесс постановки сообщений в очередь для их дальнейшей отправки провайдеру, к сожалению, выходит за рамки данного поста по многим причинам.
клиент серверное приложение php

1.2 Какими данными будем меняться?

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

И все же, я что-то забыл! Если еще немного порефлексировать, то стоит отметить, что клиент за раз может отправить на сервер как одно sms-сообщение, так и некоторое их количество. Другими словами, в одном пакете данных может быть от одного до бесконечности сообщений.

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

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

На этом мы закончили описание постановки задачи! И наконец-то приступим к самому интересному – будем разбираться что за диковинный зверь этот SOAP!

2 С чем есть SOAP?

Вообще, изначально я не планировал ничего писать о том, что такое SOAP и хотел ограничиться ссылками на сайт w3.org с нужными спецификациями, а также ссылками на Wikipedia. Но в самом конце решил написать коротенькую справочку об этом протоколе.

И начну я свое повествование с того, что данный протокол обмена данными относится к подмножеству протоколов основанных на так называемой парадигме RPC (Remote Procedure Call, удалённый вызов процедур) антиподом которой является REST (Representational State Transfer, передача репрезентативного состояния). Более подробно об этом можно прочесть в Wikipedia, ссылки на статьи находятся в самом конце топика. Из этих статей нам надо уяснить следующее: «Подход RPC позволяет использовать небольшое количество сетевых ресурсов с большим количеством методов и сложным протоколом. При подходе REST количество методов и сложность протокола строго ограничены, из-за чего количество отдельных ресурсов может быть большим». Т.е., применительно к нам это означает, что на сайте в случае RPC подхода будет всегда один вход (ссылка) на сервис и какую процедуру вызывать для обработки поступающих данных мы передаем вместе с данными, в то время как при REST подходе на нашем сайте есть много входов (ссылок), каждая из которых принимает и обрабатывает только определенные данные. Если кто-то из читающих знает, как еще проще объяснить различие в данных подходах, то обязательно пишите в комментариях!

Следующее, что нам надо узнать про SOAP – данный протокол в качестве транспорта использует тот самый XML, что с одной стороны очень хорошо, т.к. сразу же в наш арсенал попадает вся мощь стека технологий основанных на данном языке разметки, а именно XML-Schema – язык описания структуры XML-документа (спасибо Wikipedia!), который позволяет производит автоматическую валидацию поступающих на сервер данных от клиентов.

И так, теперь мы знаем, что SOAP – протокол используемый для реализации удаленного вызова процедур и в качестве транспорта он использует XML! Если почитать статью на Wikipedia, то оттуда можно узнать еще и о том, что он может использоваться поверх любого протокола прикладного уровня, а не только в паре с HTTP (к сожалению, в данном топике мы будем рассматривать только SOAP поверх HTTP). И знаете, что мне во всем этом больше всего нравится? Если нет никаких догадок, то я дам подсказку – SOAP!… Всеравно не появилось догадок?… Вы точно прочли статью на Wikipedia?… В общем, не буду вас дальше мучить. Поэтому, сразу перейду к ответу: «SOAP (от англ. Simple Object Access Protocol — простой протокол доступа к объектам; вплоть до спецификации 1.2)». Самое примечательное в этой строчке выделено курсивом! Я не знаю какие выводы сделали вы из всего этого, но мне видится следующее – поскольку данный протокол ну никак нельзя назвать «простым» (и видимо с этим согласны даже в w3), то с версии 1.2 он вообще перестал как-то расшифровываться! И стал называться SOAP, просто SOAP и точка.

Ну да ладно, прошу меня извинить, занесло немного в сторону. Как я писал ранее, в качестве транспорта используется XML, а пакеты, которые курсируют между клиентом и сервером называются SOAP-конвертами. Если рассматривать обобщенную структуру конверта, то он вам покажется очень знакомым, т.к. напоминает структуру HTML-страницы. В нем есть основной раздел – Envelop, который включает разделы Header и Body, либо Fault. В Body передаются данные и он является обязательным разделом конверта, в то время как Header является опциональным. В Header может передаваться авторизация, либо какие-либо иные данные, которые на прямую не относятся к входным данным процедур веб-сервиса. Про Fault особо рассказывать нечего, кроме того, что он приходит в клиент с сервера в случае возникновения каких-либо ошибок.
клиент серверное приложение php

На этом мой обзорный рассказ про протокол SOAP заканчивается (более детально сами конверты и их структуру мы рассмотрим когда наши клиент и сервер наконец-то научатся запускать их друг в друга) и начинается новый – про компаньона SOAP под названием WSDL (Web Services Description Language). Да-да, это та самая штука, которая отпугивает большинство из нас от самой попытки взять и реализовать свое API на данном протоколе. В результате чего, мы обычно изобретаем свой велосипед с JSON в качестве транспорта. И так, что такое WSDL? WSDL – язык описания веб-сервисов и доступа к ним, основанный на языке XML (с) Wikipedia. Если из этого определения вам не становится понятным весь сакральный смысл данной технологии, то я попытаюсь описать его своими словами!

3 Введение в XML-Schema

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

Предлагаю далеко не ходить и написать XML-схему для нашего sms-сообщения! Ниже представлено xml-описание sms-сообщения:

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

Эта запись читается следующим образом: у нас есть переменная «message» типа «Message» и есть комплексный тип с именем «Message», который состоит из последовательного набора элементов «phone» типа string, «text» типа string, «date» типа dateTime, «type» типа decimal. Эти типы простые и уже определены в описании схемы. Поздравляю! Мы только что написали нашу первую XML-схему!

Думаю, что значение элементов «element» и «complexType» вам стало все более-менее понятно, поэтому не будем на них больше заострять внимание и переключимся сразу же на элемент-композитор «sequence». Когда мы используем элемент-композитор «sequence» мы сообщаем о том, что элементы включенные в него должны всегда располагаться в указанной в схеме последовательности, а также все из них являются обязательными. Но не стоит отчаиваться! В XML-схемах есть еще два элемента-композитора: «choice» и «all». Композитор «choice» сообщает о том, что должен быть какой-то один из перечисленных в нем элементов, а композитор «all» – любая комбинация перечисленных элементов.

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

Схема для такого комплексного типа будет выглядеть так:

В первом блоке идет знакомое нам декларирование комплексного типа «Message». Если вы заметили, то в каждом простом типе, входящем в «Message», были добавлены новые уточняющие атрибуты «minOccurs» и «maxOccurs». Как не трудно догадаться из названия, первый (minOccurs) сообщает о том, что в данной последовательности должно быть минимум по одному элементу типа «phone», «text», «date» и «type», в то время как следующий (maxOccurs) атрибут нам декларирует, что таких элементов в нашей последовательности максимум по-одному. В результате, когда мы пишем свои схемы для каких-либо данных, нам предоставляется широчайший выбор по их настройке!

Второй блок схемы декларирует элемент «messageList» типа «MessageList». Видно, что «MessageList» представляет собой комплексный тип, который включает минимум один элемент «message», но максимальное число таких элементов не ограничено!

На этом будем считать, что ЛикБез по схемам завершен и далее нас ждет еще одно не менее увлекательное приключение – мы будем писать свой собственный WSDL!

4 Пишем свой WSDL

Вы помните о том, что WSDL и есть наш веб-сервис? Надеюсь, что помните! Как мы его напишем, так на нем наш маленький веб-сервис и поплывет. Поэтому, предлагаю не халтурить.

Вообще, для того, чтобы у нас все работало правильно нам надо передавать клиенту WSDL-файл с правильным MIME-типом. Для этого необходимо настроить ваш веб-сервер соответствующим образом, а именно – установить для файлов с расширением «*.wsdl» MIME-тип равный следующей строке:

Но на практике, я обычно отправлял посредством PHP HTTP-заголовок«text/xml»:

и все прекрасно работало!

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

Поскольку WSDL – это XML, то в самой первой строке необходимо прямо об этом и написать. Корневой элемент файла всегда должен называться «definitions»:

Обычно, WSDL состоит из 4-5 основных блоков. Самый первый блок – определение веб-сервиса или другими словами – точки входа.

Здесь написано, что у нас есть сервис, который называется – «SmsService». В принципе, все имена в WSDL-файле могут быть вами изменены на какие только пожелаете, т.к. они не играют абсолютно никакой роли.

После этого мы объявляем о том, что в нашем веб-сервисе «SmsService» есть точка входа («port»), которая называется «SmsServicePort». Именно в эту точку входа и будут отправляться все запросы от клиентов к серверу. И указываем в элементе «address» ссылку на файл-обработчик, который будет принимать запросы.

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

Для этого перечисляется какие операции и в каком виде у будут вызываться. Т.е. для порта «SmsServicePort» определена привязка под именем «SmsServiceBinding», которая имеет тип вызова «rpc» и в качестве протокола передачи (транспорта) используется HTTP. Т.о., мы здесь указали, что будем осуществлять RPC вызов поверх HTTP. После этого мы описываем какие процедуры (operation) поддерживаются в веб-сервисе. Мы будем поддерживать всего одну процедуру – «sendSms». Через эту процедуру будут отправляться на сервер наши замечательные сообщения! После того, как была объявлена процедура, необходимо указать в каком виде будут передаваться данные. В данном случае указано, что будут использоваться стандартные SOAP-конверты.

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

Для этого мы указываем, что наша привязка («binding») имеет тип «SmsServicePortType» и в элементе «portType» с одноименным типу именем указываем привязку процедур к сообщениям. И так, входящее сообщение (от клиента к серверу) будет называться «sendSmsRequest», а исходящее (от сервера к клиенту) «sendSmsResponse». Как и все имена в WSDL, имена входящих и исходящих сообщения – произвольные.

Теперь нам необходимо описать сами сообщения, т.е. входящие и исходящие:

Для этого мы добавляем элементы «message» с именами «sendSmsRequest» и «sendSmsResponse» соответственно. В них мы указываем, что на вход должен прийти конверт, структура которого соответствует типу данных «Request». После чего с сервера возвращается конверт содержащий тип данных – «Response».

Теперь надо сделать самую малость – добавить описание данных типов в наш WSDL-файл! И как вы думаете, как описываются в WSDL входящие и исходящие данные? Думаю, что вы уже все давно поняли и сказали сами себе, что при помощи XML-схем! И вы будете абсолютно правы!

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

5 Наш первый SOAP-сервер

Ранее я писал, что для создания SOAP-сервера на PHP мы будем использовать встроенный класс SoapServer. Для того, чтобы все дальнейшие действия происходили также как и у меня, вам понадобиться немного подкрутить свой PHP. Если быть еще точнее, то необходимо убедиться, что у вас установлено расширение «php-soap». Как его поставить на ваш веб-сервере лучше всего прочитать на официальном сайте PHP (см. список литературы).

После того, как все было установлено и настроено нам необходимо будет создать в корневой папке вашего хостинга файл «smsservice.php» со следующим содержанием:

То, что находится выше строчки с функцией «ini_set», надеюсь, что объяснять не надо. Т.к. там определяется какие HTTP-заголовки мы будем отправлять с сервера клиенту и настраивается окружение. В строчке с «ini_set» мы отключаем кеширование WSDL-файла для того, чтобы наши изменения в нем сразу же вступали в действие на клиенте.

Теперь мы подошли к серверу! Как видим, весь SOAP-сервер занимает всего лишь три строки! В первой строке мы создаем новый экземпляр объекта SoapServer и передаем ему в конструктор адрес нашего WSDL-описания веб-сервиса. Теперь мы знаем, что он будет располагаться в корне хостинга в файле с говорящим именем «smsservice.wsdl.php». Во второй строке мы сообщаем SOAP-серверу какой класс необходимо дергать для того, чтобы обработать поступивший с клиента конверт и вернуть конверт с ответом. Как вы могли догадаться, именно в этом классе будет описан наш единственный метод sendSms. В третьей строке мы запускаем сервер! Все, наш сервер готов! С чем я нас всех и поздравляю!

Теперь нам необходимо создать WSDL-файл. Для этого можно либо просто скопировать его содержимое из предыдущего раздела, либо позволить себе вольности и немного его «шаблонизировать»:

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

6 SOAP-клиент на подходе

Прежде всего нам надо создать файл, в котором будем писать клиент. Как обычно, мы его создадим в корне хоста и назовем «client.php», а внутри напишем следующее:

Опишем наши объекты. Когда мы писали WSDL в нем для входящего на сервер конверта описывались три сущности: Request, MessageList и Message. Соответственно классы Request, MessageList и Message являются отражениями этих сущностей в нашем PHP-скрипте.

После того, как мы определили объекты, нам необходимо создать объект ($req), который будем отправлять на сервер. После чего идут две самые заветные для нас строки! Наш SOAP-клиент! Верите или нет, но этого достаточно для того, чтобы на наш сервер начали сыпаться сообщения от клиента, а также для того, чтобы наш сервер успешно их принимал и обрабатывал! В первой из них мы создаем экземпляр класса SoapClient и передаем в его конструктор адрес расположения WSDL-файла, а в параметрах явно указываем, что работать мы будем по протоколу SOAP версии 1.2. В следующей строке мы вызываем метод sendSms объекта $client и сразу же выводим в браузере результат.
Давайте запусти и посмотрим что-же у нас наконец-то получилось!

Мне с сервера вернулся следующий объект:

И это замечательно, т.к. теперь мы точно знаем о том, что наш сервер работает и не просто работает, но еще и может возвращать на клиент какие-то значения!

Теперь посмотрим на лог, который мы предусмотрительно ведем на серверной стороне! В первой его части мы видим необработанные данные, которые поступили на сервер:

Это и есть конверт. Теперь вы знаете как он выглядит! Но постоянно на него любоваться нам вряд ли будет интересно, поэтому давайте десереализуем объект из лог-файла и посмотрим все ли у нас хорошо:

Как видим, объект десериализовался правильно, с чем я нас всех хочу поздравить! Далее нас ждет что-то более интересно! А именно – мы будем отправлять клиентом на сервер не одно sms-сообщение, а целую пачку (если быть точнее, то целых три)!

7 Отправляем сложные объекты

Давайте подумаем над тем, как же нам передать целую пачку сообщений на сервер в одном пакете? Наверно, самым простым способом будет организация массива внутри элемента messageList! Давайте это сделаем:

В наших логах числится, что пришел следующий пакет от клиента:

Что за ерунда, скажете вы? И будете правы в некотором смысле, т.к. только что мы узнали о том, что какой объект ушел от клиента, то абсолютно в том же виде он пришел к нам на сервер в виде конверта. Правда, sms-сообщения сериализовались в XML не так, как нам было необходимо – они должны были быть обернуты в элементы message, а не в Struct. Теперь посмотрим в каком виде приходит такой объект в метод sendSms:

Что нам дает это знание? Только то, что выбранный нами путь не является верным и мы не получили ответа на вопрос – «Как нам на сервере получить правильную структуру данных?». Но я предлагаю не отчаиваться и попробовать привести наш массив к типу объект:

В этом случае, нам придет уже другой конверт:

Пришедший в метод sendSms объект имеет следующую структуру:

Как по мне, то «от перемены мест слагаемых – сумма не меняется» (с). Что BOGUS, что Struct – цель нами до сих пор не достигнута! А для ее достижения нам необходимо сделать так, чтобы вместо этих непонятных названий отображалось наше родное message. Но как этого добиться, автору пока не известно. Поэтому единственное, что мы можем сделать – избавить от лишнего контейнера. Другими словами, мы сейчас сделаем так, чтобы вместо message стал BOGUS! Для этого изменим объект следующим образом:

Вдруг нам повезет и из схемы подтянется правильное название? Для этого посмотрим на пришедший конверт:

Да, чуда не произошло! BOGUS – не победим! Пришедший в sendSms объект в этом случае будет выглядеть следующим образом:

Как говорится – «Почти»! На этой (немного печальной) ноте предлагаю потихонечку закругляться и сделать некоторые для себя выводы.

8 Заключение

Источник

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

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