SOAP/WSDL vs XML data exchange.
Я уже в сотый раз наталкиваюсь на странные разговоры, когда человек начинает говорить о протокольном обмене по XML - потом вдруг сьезжает на интерфейс SOAP/WSDL и обратно в XML. Такая каша в головах! Причем даже не только у выживших из ума пенсионеров от программирования - но даже у практикующих программистов!
В связи с этим я решил написать эту краткую реплику - чтобы каждый раз не пережевывать заново азбучные истины - а просто отсылать заблудившихся в этот топик.
Во-первых, SOAP и XML - это разные режимы работы IIS (или Apache) - разные в смысле выдаваемых заголовков респонса. Обмен по протоколу XML - это простой обмен по протоколу HTTP 1.1. Кто не понимает этих простых вещей - посмотрите на заголовки - они совершенно разные при обмене по SOAP и по XML - соответственно IIS/Apache работает по разным алгоритмам, обслуживая эти реквесты и выдавая респонзы.
Во-вторых, если обмен по XML реализуется программистом самостоятельно - фактически это простой reqsponse.write в поток браузера, то SOAP/WSDL обмен имеет (на микрософтовской платформе) две стандартные реализации. Две библиотеки, которые выполняют всю черновую работу - старый формат - ASMX-сервисы и новый WCF-сервисы.
То есть SOAP/WSDL сервис уже не программируется ВРУЧНУЮ программистом, а программируются только некоторые фишечки - (определения интерфейсов и их реализация) - которые скармливаются общему движку построения сервиса (библиотеке) - которая и выдает в результате WSDL (схему работы сервиса) и формирует общий алгоритм работы сервиса - например с сессиями, без сессий, синглтон-сервис и так далее. Соответственно, технология программирования не имеет ничего общего - в варианте обмена по XML вы самостоятельно что-то реализуете (что успеваете в рамках бюджета проекта), в варианте SOAP - вы должны встроить совсем немного своего личного кода в адскую по обьему библиотеку - но как все это будет работать в итоге - зависит от вашего понимания работы этого движка.
Хочу сказать, что движок этот в принципе неплохой, но работает он НЕ ВСЕГДА хорошо. И для тех случаев, когда он ГЛЮЧИТ - я написал СВОЮ соственную замену стандартному движку (клиенту) - с которым вы можете познакомиться здесь - WCF_CLIENT - клиент Web-сервиса (вторая версия).
В-третьих, если у вас есть SOAP/WSDL-сервис, то есть и WSDL-файл с описанием интерфейса. Ибо WSDL - это и есть специальный файлик для описания любых интерфейсов. Чтобы это стало понятно - я выпущу сейчас WSDL просто по ЛЮБОЙ произвольной своей библиотеке, например моей публичной библиотеке AspCommon2009.dll, которая представляет собой некоторую надстройку над ASP.NET и которую я использую почти во всех своих сайтах (в том числе распространяемых мною ClosedSource сайтах, например AspNet_UserManager). Кстати эта моя библиотека подвергалась обфускации, что не мешает построить по всем типам данных в ней и по всем ее публичным интерфейсам WSDL.
Более того, я не просто могу посмотреть в различных представлениях на WSDL с помощью например Альтовы, но я могу просто поставить ссылку в студии не на реальную локальную DLL, а на ее WSDL-описание. При этом Object Browser из Visual Studio будет прекрасно отображать всю иерархию классов и все типы данных из WSDL-описания библиотеки. Для такой операции лучше использовать не какую-то произвольную обфусканную библиотеку - обычно так делают для доступа к удаленной библиотеке, которая экспортирует некоторые сервисы. При этом классы доступные для вызова удаленно, должны быть помечены специальными атрибутами - ServiceContract, OperationContract, DataContract.
Для примера, ниже я поставлю ссылку на контракт платежного шлюза Inplat:
Вот во что превратился вот этот WSDL-файл. Никакого подобного файла не будет и в помине при обмене вашими собственными XML (ну разве что вы сами убьете себя ап стену и составите точные и правильные XML-схемы документов с исчерпывающими проверками всех параметров и формата всех параметров и будете каждый отправляемый и каждый принимаемый XML сверять со схемой обмена).
В нижеследующем примере я построю сервис с двусторонним обменом по SOAP/WSDL причем некий конкретный платежный шлюз (в целом о платежных шлюзах вы можете почитать тут - Шлюзы к платежным системам интернет-денег) дает мне готовое (в формате WSDL) описание - как именно должен быть устроен мой SOAP-шлюз: мой SOAP-сервис должен иметь четыре метода ArbitraryMessage, PaymentAuthorization, PaymentCancellation, PaymentContract (у каждого из которых ТОЧНО специфицирована масса параметров) и я, в свою очередь, могу вызывать восемь методов платежного шлюза: CheckPayment, ConfirmPayments, GetPayment, GetPayments, InitPayment, InitUnregisteredCardPayment, SendMessage, SendRoster c точно заданными параметрами.
Чтобы мне обратиться к удаленному SOAP-серверу с интерфейсом, специфицированном WSDL - я просто ставлю в проекте ссылку на сервис и могу пользоваться готовым (сгенерированным студией) прокси-классом, который мне дает с подсказкой все методы удаленного сервиса и все параметры каждого метода (совершенно не заботясь сериализацией параметоров и обьектов в XML, проходящих по сети).
Как видите, подобное WSDL-описание ИСЧЕРПЫВАЮЩЕ описывает порядок обмена данными между моей софтиной и платежным шлюзом. Чтобы допустить какую-то ошибку в протокольном обмене взаимодействия между софтинами - надо постараться очень-очень. Надеюсь здесь достаточно очевидно НАСКОЛЬКО это взаимодействие отличается от взаимодействия с помощью RAW XML. Фактически в несколько кликов мышкой я АБСОЛЮТНО НАДЕЖНО связал по сети две удаленные софтины - причем компилятор просто не скомпилирует мою софтину если у нее хоть один параметр будет не соответствовать WSDL-описанию, например я буду вызывать несуществующий метод или буду пытаться пихать в параметр какого-то метода дату вместо целого числа.
В-четвертых, WSDL-файл может быть построен не только по любому существующему интерфейсу (как я показал выше), но и наоборот по любому (заведомо известному WSDL) может быть автоматически или вручную сгенерирован код интерфейса.
Единственное, на что надо обратить внимание при ручном построении интерфейсов, на правильные пространства имен. Впрочем и утилита автоматического построения интерфейса требует некоторой ручной корректировки - она ставит слишком сложные атрибуты, требующие слишком сложной настройки в web-конфиге - эти атрибуты проще удалить, как и сложный громоздкий сгенерированный конфиг, в котором перечислены сплошные умолчания.
Вот как делается автоматическое построение интерфейсов обмена данными утилитой svcutil:
Более того, с некоторыми мелкими программисткими ухищрениями (см скрины) - создать сразу весь интерфейс вашего SOAP/WSDL-сервиса ВРУЧНУЮ - даже безо всяких утилит автоматизации. Сначала ставим ссылку, чтобы прочитать этот WSDL, а потом можно просто перенести копипастом из прокси-класса Reference.vb методы со всеми параметрами в свой собственный SOAP-сервис. Сначала я строю определения интерфейсов (IInPlatGateway) - по которым движок построит WSDL и высунет определения моего сервиса внаружу. А потом захожу в реализацию - один тычок в Enter и реализация класса заполнится определенными в интерфейсе методами. Все мой сервис готов - теперь можно только наполнять содержимым алгоритмы и параметры вызовов - точная связь софтин гарантирована.
В-пятых, стандартный микрософтовский движок SOAP/WSDL-сервиса (второй версии-WCF) - имеет АДСКОЕ количество конфигурационных параметров движка, которые вынесены в web-config и вы можете эти параметры как конфигурировать вручную (текстом в конфиге), так и в диалоговых инструментах. Это сотни (скорее даже тысячи) параметров, управляющих работой движка web-сервиса. Их надо знать и они позволяют модифицировать служебные алгоритмы движка как угодно, ну например вообще избавиться при обмене от XML и проводить обмен бинарными данными.
В-шестых, если вы написали какой-то свой код, при котором приложения обмениваются какими-то собственными XML - то вам придется и самому реализовывать журнал этого обмена, в котором вы будет сохранять трассировку обмена. ВАм придется делать вот такие намордники http://airts.vb-net.com/ - в котором вы будете формировать разные XML-запросы и смотреть что будет отвечать ваш web-сервис.
При работе с SOAP/WSDL ничего подобного не будет. Для тестовых обращений к своему сервисы вы будете (скорее всего) использовать или готовый микрософтовский тестер SOAP/WSDL сервисов (WCFTestClient.exe) или Альтову:
В-седьмых, над WSDL-описанием экспортируемых в сеть сервисов - существует множество надстроек. Например ОБОЗРЕВАТЕЛИ всех доступных сервисов в сети. И все стандартные инструменты построения SOAP-WSDL сервисов сразу же обеспечивают функционирование и этих производных сервисов.
Практически, в Visual Studio, Eclipse, Netbeans и прочих инструментах достаточно нажать одну кнопку, чтобы убедиться что сервис виден из данный точки сети, доступен, можно прочитать его контракт и обратиться к нему (если конечно это разрешено режимом безопасности сервиса).
Фактически у обмена по XML и по SOAP/WSDL столько разного, что трудно даже найти что-нибудь общее между этими сущностями. Я вообще затрудняюсь найти что-то общее - кроме того, что и одно и второе - это механизм обмена данными между приложениями по сети. Поэтому у меня и вызывает удивление, когда не только левые пенсионеры от программирования, но даже практикующие программисты ухитряются найти что-то общее в технологиях обмена данными сырыми XML и обмена данными по SOAP/WSDL.
Какая же технология обмена лучше? Однозначного ответа нет - все зависит от конкретной постановки вашей задачи. А ваш опыт (или его отсутствие) проявляется как раз в выборе НЕ ТОЙ технологии, которая оптимальна для решения вашей конкретной задачки. Что касается меня лично - то я пишу обмены и по XML и по SOAP/WSDL (в зависимости от ситуации). А иногда изобретаю и собственные протоколы обмена, не похожие на привычные SOAP/WSDL или RAW XML. Вы можете почитать мои обучающие инструкции и на одну и на вторую тему:
- SOAP/WSDL :
- Как сделать SOAP/WSDL-вебсервис на ASP.NET/MONO для вызова его из FLEX - общая обзорная экскурсия в тему SOAP/WSDL.
- Как парсить XML SOAP в MS SQL - здесь обработка SOAP-WSDL сервиса выполняется внутри MS SQL сервера с помощью SQL CRL сборки.
- Обращение к SOAP/WSDL сервису по SSL :
- Мой собственный клиент для обращения к SOAP/WSDL сервису :
- XML :
- Как сделать простейший Web-handler - формирующий XML или JSON. - общая обзорная экскурсия по обмену приложений с помощью XML.
- Шлюз к 1С по протоколу Битрикс. - еще мой один классический XML-шлюз.
- SQL-Client_for_remote_XML-WebService - клиент meteonova.ru. - здесь обмен сырыми XML выполняется из SQL CLR сборки, работающей прямо внутри процесса MS SQL сервера.
- Text :
- GoogleTranslate - англо-русский онлайн переводчик. - Простые запросы/ответы в виде текста тоже часто используются.
- JSON :
- Заполнение связанных списков на MS AJAX и jQuery. - Из Javascript обращаются на сервера обычно по JSON
- AJAX подсказка/автозаполнение на jQuery.
- Сокетная связь :
- Этюды на ASP2. Обращение к Whois-сервису. - к DNS-серверам тоже так обращаются.
- Сокеты во Flash. - видео/аудио/игры - это тоже сокеты.
- Односторонняя FTP/ZIP связь :
- Скачка, раззиповка, перекодирование, парсинг и укладка в базу ЖД-расписания из АСУ Экспресс-3. - так обычно выкладываются большие прайс-листы.
- Текстовый загрузчик/конвертер данных с FTP в базу
- Періодична публікація ділерського прайсу.
- Самописные протоколы собственного изобретения :
- Remote SQL execute for PostgreSQL on GSM/GPRS channel with extreme compress and cryptography. - в этом варианте я придумал собственный протокол обмена - не связанный со стандартными XML или SOAP.
- WebActivator - клиент/сервер защиты от копирования для платных программ. - здесь производится обмен между защищаемой от копирования программы и сервером защиты по моему собственному "псевдо-SSL" протоколу, причем засчет моего собственного протокола защита передаваемый по сети данных доведена до уровня паранойи.
|