Pergunta

Eu estou tentando implementar um serviço de web stateful em PHP usando a extensão SOAP. (Sim, eu sei que os serviços web são suposto ser apátrida; tudo o que realmente importa para persistir alguma forma de um ID de sessão para que eu não precisa se autenticar com cada chamada para o serviço). do PHP.net documentação da API é um pouco carente sobre isso, e não há muito mais escrito nele.

Eu encontrei uma página que discute isso ( http://bytes.com/forum/thread160816.html ) e implementou o código como um teste. Eu construí uma pequena aplicação .NET que consome o serviço Web e chama cada função e exibe o resultado. Pelo que tenho lido, a extensão PHP SABÃO persistirá variáveis ??de classe entre chamadas, desde que a funcionalidade é encapsulado em uma classe usando a função setClass () eo setPersistence () função é SOAP_PERSISTENCE_SESSION passado.

Aqui está o meu código:

<?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();

?>

O problema que eu correr em é que $ name não é mantida entre as chamadas - Eu sempre obter o valor inicializado e não o valor que atribuo ao setName (). Como eu disse, eu estou tentando persistir um ID sessão após autenticar em um banco de dados - se alguém tem uma maneira melhor de fazer isso estou aberto a sugestões; No entanto, eu ainda gostaria de resolver o caso geral. Alguém tem alguma idéia?

Foi útil?

Solução

Na verdade, eu resolvido meu problema.

Eu estava trabalhando sob os pressupostos que: 1) .NET manipula os cookies automaticamente; e 2) o meu problema foi com o PHP. Nem era o caso. Meu código PHP era bom, mas eu precisava para adicionar mais um elemento para o meu código .NET para lidar com o cookie de sessão.

Depois de instanciar o objeto de serviço web, que eu precisava para atribuir uma instância da classe CookieContainer para o objeto de serviço web. Meu código do lado do cliente final é abaixo:

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();
        }
    }
}

Obrigado de qualquer forma!

Outras dicas

A maioria dos clientes de sabão iniciar uma nova conexão para cada solicitação para que não haja "sessão".

Se o seu serviço SOAP que você poderia enviar a algum lugar dentro ID de sessão no envelope SOAP em cada resposta e pedir ao cliente para passar o id de sessão em cada solicitação subseqüente.

Este é muito mais agradável como o seu cliente tem agora pista e controle sobre a beheaviour.

Para consumir o serviço web stateful, você precisa definir o ID da sessão da sessão do servidor no cookie de SOAP no lado do cliente. Por padrão, cada solicitação SOAP tempo é enviado, o servidor gera uma identificação de sessão exclusiva. Para evitar que apenas definir o ID da sessão tem de primeiro pedido no cookie SOAP. Esse cookie será enviado com as chamadas de sabão todos os subseqüentes. Por exemplo, se você está consumindo um sabonete ASP.net webservice usando, em seguida, após a primeira chamada WS, obter os cabeçalhos de resposta como esta:

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

Agora $headers deve conter a identificação da sessão com um nome como 'ASP.NET_SessionId'. Obter o ID do $headers e criar um cookie da seguinte forma:

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

Agora, todas as solicitações SOAP de seu cliente irá conter o ID da sessão e seu estado irá persistir no servidor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top