Love via soap I: asmx + php

14 февр. 2012 г. | | |

Задача очень простая: есть сервис на ASP.NET (asmx-сервис) и есть клиент на php, и нужно научить их общаться по http. Всё это просто реализуется через протокол SOAP.

1.    Немного теории

SOAP (расшифровывается как Simple Object Access Protocol)– это стандарт, который позволяет  описать удаленный вызов (RPC) и вид, в котором будет возвращаться результат, и всё это в xml. Т.е. и сервис, и клиент должны уметь понимать SOAР-пакеты, а на чем они реализованы (да хоть на паскале), уже никого не волнует.

1.1.    Пример asmx-сервиса
Простейший пример SOAP-сервиса, реализованного через asmx-сервис, можно посмотреть тут http://www.deeptraining.com/webservices/weather.asmx Сервис сообщает данные о погоде для конкретного города в США, название которого получает входным параметром. Посмотреть структуру сервиса можно, указав команду wsdl: http://www.deeptraining.com/webservices/weather.asmx?wsdl
WSDL – это не магия, а всего лишь язык описания веб-сервисов, который дает возможность посмотреть расположение сервиса и операции (или методы), предоставляемые им, в виде xml-документа. WSDL-документ необходим клиенту, чтобы знать, как правильно обращаться к сервису, не зная его внутренней структуры. Посмотрев на документ, мы уже знаем, что сервис располагает методом GetWeather, в котором нужно указать название города для того, чтобы получить прогноз погоды. И этого достаточно для общения клиента и сервиса.
Изнутри сервис выглядит где-то так (weather.asmx):

<%@ WebService Language="C#" Class="WeatherService" %>

using System;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService (
    Name="Weather Service",
    Description="Provides weather forcasts for U.S. cities"
)]
public class WeatherService
{
    [WebMethod (Description="Returns the weather for a given city")]
    public decimal GetWeather (string City)
    {
    var weather = String.Empty;
    //как-то получаем данные о погоде
        return weather;
    }
}


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

1.2.    Пример клиента на php
В php есть специальный класс, SoapClient, который избавляет нас от тягомотины писать свою обёртку для работы с SOAP-сервисами. Класс умеет работать с протоколами SOAP версии 1.1 и 1.2 и доступен начиная с версии php 5.0.1.Наверно, стоит упомянуть библиотеку NuSoap, которая также позволяет легко общаться с веб-сервисами через SOAP, но она была актуальна тогда, когда php не имел встроенной поддержки протокола.

Чтобы вызвать метод GetWeather веб-сервиса (о наличии метода нам поведал wsdl-документ), нужно написать всего лишь пару строчек кода:

$client = new SoapClient("http://www.deeptraining.com/webservices/weather.asmx?WSDL");
$weather = $client->GetWeather(array('City' => 'New York'))->GetWeatherResult;
echo $weather;


SoapClient создаёт для нас объект по структуре сервиса, полученного из его wsdl. Вызываем метод, которому даём  ассоциативный массив с входным параметром (в wsdl-структуре описано, что входной параметр должен иметь имя City и быть строковым типом), и получаем ответ в виде объекта с полем GetWeatherResult, тоже строкового типа (это тоже описано в wsdl-документе). «Sunny», говорит сервис :) Для примера, вызовем немного неправильно метод GetWeather, указав неправильно имя входного параметра:

$client = new SoapClient("http://www.deeptraining.com/webservices/weather.asmx?WSDL");
$weather = $client->GetWeather(array('Town' => 'New York'))->GetWeatherResult;
echo $weather;


И получим Fatal error (ведь Нью-Йорк не town :) ):

Fatal error: Uncaught SoapFault exception: [soap:Server] System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Weather.GetWeather(String City) 

Мораль: все параметры должны иметь имена (и параметры) в точности такие, как требует того структура сервиса.


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

1 коммент.:

Alex Nikolas комментирует...

Просто и доступно. Как раз то, что искал. Никакой воды.
Никогда не работал с SOAP. А тут нежданно поступила вводная.
В Яндексе ссылка оказалась на первом месте по запросу "PHP SOAP asmx"

Отправить комментарий