Веб-сервис PHP с сохранением состояния с использованием SOAP - PullRequest
1 голос
/ 17 ноября 2008

Я пытаюсь реализовать веб-сервис с отслеживанием состояния в PHP, используя расширение SOAP. (Да, я знаю, что веб-сервисы должны быть без сохранения состояния; все, что я действительно хочу сохранить - это какая-то форма идентификатора сеанса, поэтому мне не нужно проходить аутентификацию при каждом обращении к сервису). Документация по API в PHP.net в некоторой степени отсутствует по этому поводу, и больше ничего не написано.

Я нашел одну страницу, которая обсуждает это (http://bytes.com/forum/thread160816.html), и реализовал код в качестве теста. Я создал небольшое приложение .NET, которое использует веб-сервис, вызывает каждую функцию и отображает результат. Из того, что я ' прочитав, расширение PHP SOAP будет сохранять переменные класса между вызовами до тех пор, пока функциональность инкапсулирована в класс с помощью функции setClass () и функция setPersistence () передана SOAP_PERSISTENCE_SESSION.

Вот мой код:

<?php

class User 
{
    var $name = "Initial value";

    function setName($name) 
    {
        $this->name = $name;

        // Tried this too.
        // $this->name = "Set to string constant" ;
    }

    function getName() 
    {
        // This always returns "Initial value"
        return $this->name;
    }
}


// Tried placing session_start() in several places
// before $server->handle()...
// One guy says this doesn't need to be called.
// I assume it depends on if session autostart is on.
session_start();

$server = new SoapServer(null, array('uri' => 'http://localhost/'));
$server->setClass('User');
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();

?>

Проблема, с которой я сталкиваюсь, заключается в том, что $ name не сохраняется между вызовами - я всегда получаю инициализированное значение, а не значение, которое я назначаю setName (). Как я уже говорил, я пытаюсь сохранить идентификатор сеанса после аутентификации в базе данных - если у кого-то есть лучший способ сделать это, я открыт для предложений; Тем не менее, я все еще хотел бы решить общий случай. У кого-нибудь есть идеи?

Ответы [ 3 ]

1 голос
/ 18 ноября 2008

Я на самом деле решил свою проблему.

Я работал в предположении, что: 1) .NET автоматически обрабатывает куки; и 2) моя проблема была с PHP. Ни один не был случай. Мой PHP-код был в порядке, но мне нужно было добавить еще один элемент в мой .NET-код для обработки cookie сеанса.

После создания экземпляра объекта веб-службы мне нужно было назначить экземпляр класса CookieContainer для объекта веб-службы. Мой окончательный код на стороне клиента ниже:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WsTest
{
    public partial class PhpWsForm : Form
    {
        private localhost.MyWebService ws;

        public PhpWsForm()
        {
            InitializeComponent();
            ws = new WsTest.localhost.MyWebService();

            // The line below is the part that I forgot!
            ws.CookieContainer = new System.Net.CookieContainer();
        }

        private void butSetVal_Click(object sender, EventArgs e)
        {
            ws.setName(txtSetVal.Text);
        }

        private void butGetVal_Click(object sender, EventArgs e)
        {
            txtGetVal.Text = ws.getName();
        }
    }
}

Спасибо в любом случае!

0 голосов
/ 13 апреля 2012

Для использования веб-службы с отслеживанием состояния необходимо установить идентификатор сеанса сеанса сервера в файле cookie SOAP на стороне клиента. По умолчанию каждый раз, когда отправляется запрос SOAP, сервер генерирует уникальный идентификатор сеанса. Чтобы предотвратить это, просто установите идентификатор сеанса, полученный из первого запроса в SOAP cookie. Этот файл cookie будет отправлен вместе со всеми последующими мыльными вызовами. Например, если вы используете веб-сервис ASP.net с использованием SOAP, то после первого вызова WS получите заголовки ответа, например:

$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
$headers = $client->__getLastResponseHeaders();

Теперь $headers должен содержать идентификатор сеанса с именем, подобным «ASP.NET_SessionId». Получите идентификатор из $headers и создайте файл cookie следующим образом:

//$client->__setCookie($cookieName, $cookieValue);
$client->__setCookie('ASP.NET_SessionId', $cookieValue);

Теперь все запросы SOAP от вашего клиента будут содержать этот идентификатор сеанса, и ваше состояние будет сохраняться на сервере.

0 голосов
/ 17 ноября 2008

Большинство мыльных клиентов запускают новое соединение для каждого запроса, поэтому «сеанс» отсутствует.

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

Это намного приятнее, так как ваш клиент теперь знает и контролирует поведение.

...