XML-обмен данными

27 марта 2008 года, 22:51

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

Обоснованность выбора

Выбор XML — это мой личный выбор, который удовлетворяет моим целям. Вы можете выбрать для обмена сообщениями какой-либо другой протокол (SOAP, XML-RPC или другие), либо же реализовать свой, в конечном счёте.

Структура сообщения

Каждое сообщение начинается с заголовка сообщения и одновременно единственно-возможного корня XML-дерева.

<query type="request[/response/error]"> <!-- Сообщение --> </query>

Типы сообщения. Запрос и ответ

Тип сообщения может быть различным, но в целом он сводится к типам связи между сервером и клиентом. Request — это сообщение от клиента к серверу, response — это сообщение от сервера к клиенту, а error — это сообщение об ошибке, которые можно послать в обе стороны.

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

<query type="request"> <method name="example"> <value type="integer">5</value> <value type="boolean">true</value> </method> </query>

Тип может быть либо request, либо response. Методов как при запросе, так и при ответе может быть неограниченное количество. В каждый метод могут быть включены аргументы для вызова функции (при наличии данных аргументов). Каждый аргумент должен быть разделён по типу, чтобы правильно определить разбор типов.

Типы данных

Данные при передаче могут быть следующего рода:

  • integer — целочисленные величины
  • float — величины с плавающей точкой
  • string — строковые величины
  • boolean — булевы величины (true, false или 1, 0)
  • array — массивы (сериализуются и/или кодируются в base64 по определённым алгоритмам)

Все величины, кроме array, пересылаются в чистом виде, без обработки на стороне сервера/клиента.

Сообщение об ошибке

Сообщение об ошибке несколько отличается от двух других видов сообщений.

<query type="error"> <message>Error string 1</message> <message>Error string 2</message> </query>

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

Реализация

Я реализовал приложение, называемое xmlapi, которое реализует сервер для подобного формата обмена сообщениями.

Мнения (19)

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

  • Fiat[defis]88

    28 марта 2008 г.01:58

    А как же клиент? =)
    Хм... А не может ли сервер сам отправить запрос клиенту? То есть, клиент отправил серверу запрос, и серверу допустим надо что-то уточнить, и он вместо ответа шлёт запрос клиенту....

  • Fiat[defis]88

    28 марта 2008 г.02:06

    Хотя, да, тут придётся поддерживать подключение, и сообщать о завершении сессии...

  • Dragon

    28 марта 2008 г.02:45

    Вместо ответа шлет запрос? :-) А какая разница между "ответом" и "запросом"? :-))

  • Дин автор

    28 марта 2008 г.10:05

    Разницы чёткой нет, но логика нарушена. Представь, что Apache будет слать GET/POST запросы твоему браузеру, а тот в свою очередь будет Web-серверу отдавать какой-либо контент. Отлично, да? :)

  • Mischka

    28 марта 2008 г.17:24

    Почему бы и нет? :) Ведь оба они не предназначены для таких действий.
    ИМХО, разница между клиентом и сервером чисто номинальная и существует только в мозгу человека, пытающегося понять преимущества клиент-серверных технологий. По сути же, все устройства, обменивающиеся данными по сети, являются и серверами, и клиентами в разные моменты времени.

    Если надо, могу вписать сюда пример и про апачу с браузером :)

  • Дин автор

    28 марта 2008 г.17:32

    Давай пример.

  • Mischka

    28 марта 2008 г.18:43

    Куки и сессии. Апач «запрашивает» у клиента адрес и GET-параметры для идентификации пользователя. Браузер отдает уникальный ИД сессии. Кто скажет что-то насчет инициатора обмена данными, пусть первым бросит в меня камень. Опеределение клиента и сервера под инициативу не подходят.
    Dragon уже справедливо спрашивал в чем разница между «запросом» и «ответом». Мы-то с вами знаем, что разницы нет :) Все взаимодействие определяется протоколом.
    А уж если говорить об универсальном обмене данными (который и обсуждается в статье), термины «клиент» и «сервер» слишком относительны, и иногда вредны.

  • Дин автор

    28 марта 2008 г.18:50

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

    Допустим, тот же Apache: даже если «убрать» протокол, то останутся функции, которые может выполнять только клиент и те, которые может выполнять лишь сервер. В том-то и суть разделения клиентской части и серверной (JavaScript так же никогда не станет PHP и их справедливо разделяют на языки клиентской и серверной стороны соответственно).

  • Дин автор

    28 марта 2008 г.17:45

    Кстати, не всегда разница между клиентом и сервером сводится к логическому разделению. Тот же Web-сервер: он никогда не будет выполнять такие функции, как парсинг (X)HTML, CSS, JavaScript для его запуска или для иных целей. Для этого есть браузер. Web-сервер — он предназначен лишь для того, чтобы отдавать содержимое файлов обратно пользователю, пропустив его через указанные администратором фильтры. Всё-таки грань существует, причём не такая уж она и виртуальная. :)

  • DnAp

    28 марта 2008 г.08:38

    Хотелось бы увидеть в ближайших выпусках реализацию на стороне клиента.
    Мне просто всегда казалось что на JS распарсить XML сложнее.

  • Дин автор

    28 марта 2008 г.10:04

    JavaScript? Ой, а я планировал на C++ клиент написать...

  • DnAp

    28 марта 2008 г.10:07

    А я то думал ты про web...
    А пчму тогда генерация на php а не на том-же си?

  • Дин автор

    28 марта 2008 г.10:15

    Должно же быть хоть какое-то разнообразие в языках, на то он и клиент сервер. Зачем мне генерация на C++?

  • Mischka

    28 марта 2008 г.17:16

    Не знаю про С++, но в js XML парсится очень легко. Я, не имея опыта работы с XML и должного опыта работы с js, распарсил нужные мне ответы сервера за 10 минут.

  • Дин автор

    28 марта 2008 г.17:31

    На JavaScript легко обрабатывать XML. Я даже статью писал по этому поводу.

  • CBuH

    06 мая 2008 г.22:12

    А сам клинт будет, хотя бы на с/с++? :)

  • Дин автор

    07 мая 2008 г.06:32

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

  • Дин автор

    07 июня 2008 г.17:04

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

  • Евгений

    06 июня 2009 г.14:08

    function createXMLDoc(text){ if(window.ActiveXObject){ var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); xmldoc.async = false; xmldoc.loadXML(text); return xmldoc; }else if(window.XMLHttpRequest){ var parser = new DOMParser(); return parser.parseFromString(text,"text/xml"); } return null; }

Я тоже знаю!

Для обращения к человеку используйте символ @, после которого следует имя того, к кому обращаетесь (пробелы заменяются на знак подчёркивания). Если вам интересно, можете подписаться на комментарии по RSS или по эл. почте. Ведите себя достойно, вы же не роботы, правда?

Вы можете использовать следующие XHTML-элементы в разметке комментария: strong, em, span[class=crossline], a[href=uri], code[type=язык], blockquote, ul и ol. В качестве языка кода может быть указан, например, javascript или css.