Как использовать сервис PHP SOAP с использованием WCF - PullRequest
2 голосов
/ 08 июня 2010

Я новичок в веб-сервисах, поэтому извините меня, если я здесь совершил какую-то кардинальную ошибку, хе-хе.

Я создал сервис SOAP с использованием PHP.Сервис совместим с SOAP 1.2, и у меня есть WSDL.Я включил сеансы, чтобы я мог отслеживать состояние входа в систему и т. Д.

Мне здесь не нужна супер-безопасность (то есть защита на уровне сообщений), все, что мне нужно, - это безопасность транспорта (HTTPS), так как этосервис будет использоваться нечасто, и производительность не так уж и важна.

У меня возникают трудности с его работой вообще.C # выдает неясное исключение («Сервер вернул недопустимую ошибку SOAP. Дополнительные сведения см. В InnerException». Это, в свою очередь, говорит «Несвязанный префикс, используемый в квалифицированном имени« rpc: MethodNotPresent ».»), Но использует службу с использованием клиента PHP SOAP.ведет себя как положено (включая сессию и все).

Пока у меня есть следующий код. примечание: из-за количества реального кода я публикую минимальную конфигурацию кода

PHP SOAP-сервер (с использованием библиотеки Zend Soap Server), включая класс (ы), предоставляемые через службу:

<?php

class Verification_LiteralDocumentProxy {

    protected $instance;

    public function __call($methodName, $args)
    {
        if ($this->instance === null)
        {
            $this->instance = new Verification();
        }

        $result = call_user_func_array(array($this->instance, $methodName), $args[0]);
        return array($methodName.'Result' => $result);
    }
}

class Verification {

    private $guid = '';
    private $hwid = '';

    /**
    * Initialize connection
    *
    * @param string GUID
    * @param string HWID
    * @return bool
    */
    public function Initialize($guid, $hwid)
    {
        $this->guid = $guid;
        $this->hwid = $hwid;
        return true;
    }

    /**
    * Closes session
    *
    * @return void
    */
    public function Close()
    {
        // if session is working, $this->hwid and $this->guid
        // should contain non-empty values
    }
}

// start up session stuff
$sess = Session::instance();

require_once 'Zend/Soap/Server.php';
$server = new Zend_Soap_Server('https://www.somesite.com/api?wsdl');

$server->setClass('Verification_LiteralDocumentProxy');

$server->setPersistence(SOAP_PERSISTENCE_SESSION);

$server->handle();

WSDL:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="https://www.somesite.com/api" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="Verification" targetNamespace="https://www.somesite.com/api">
    <types>
        <xsd:schema targetNamespace="https://www.somesite.com/api">
            <xsd:element name="Initialize">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="guid" type="xsd:string"/>
                        <xsd:element name="hwid" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="InitializeResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="InitializeResult" type="xsd:boolean"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="Close">
                <xsd:complexType/>
            </xsd:element>
        </xsd:schema>
    </types>
    <portType name="VerificationPort">
        <operation name="Initialize">
            <documentation>
                Initializes connection with server</documentation>
            <input message="tns:InitializeIn"/>
            <output message="tns:InitializeOut"/>
        </operation>
        <operation name="Close">
            <documentation>
                Closes session between client and server</documentation>
            <input message="tns:CloseIn"/>
        </operation>
    </portType>
    <binding name="VerificationBinding" type="tns:VerificationPort">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="Initialize">
            <soap:operation soapAction="https://www.somesite.com/api#Initialize"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
        <operation name="Close">
            <soap:operation soapAction="https://www.somesite.com/api#Close"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="VerificationService">
        <port name="VerificationPort" binding="tns:VerificationBinding">
            <soap:address location="https://www.somesite.com/api"/>
        </port>
    </service>
    <message name="InitializeIn">
        <part name="parameters" element="tns:Initialize"/>
    </message>
    <message name="InitializeOut">
        <part name="parameters" element="tns:InitializeResponse"/>
    </message>
    <message name="CloseIn">
        <part name="parameters" element="tns:Close"/>
    </message>
</definitions>

И, наконец, код потребителя WCF C #:

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IVerification
{
    [OperationContract(Action = "Initialize", IsInitiating = true)]
    bool Initialize(string guid, string hwid);

    [OperationContract(Action = "Close", IsInitiating = false, IsTerminating = true)]
    void Close();
}

class Program
{
    static void Main(string[] args)
    {
        WSHttpBinding whb = new WSHttpBinding(SecurityMode.Transport, true);

        ChannelFactory<IVerification> cf = new ChannelFactory<IVerification>(
            whb, "https://www.somesite.com/api");

        IVerification client = cf.CreateChannel();

        Console.WriteLine(client.Initialize("123451515", "15498518").ToString());
        client.Close();
    }
}

Есть идеи?Что я тут не так делаю?

1 Ответ

2 голосов
/ 11 июня 2010

Вы пытались сгенерировать клиентский прокси из wsdl?Либо локальная копия с контрактами данных (схемы XML), либо размещенный wsdl.

Вы сможете создать простое консольное приложение C #, выполнить «Добавить ссылку на службу ...» на wsdl и создатьпрокси.Код клиента будет сгенерирован автоматически, а app.config будет содержать информацию о привязке и конечную точку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...