문제

SOAP 확장을 사용하여 PHP에서 상태 가득한 웹 서비스를 구현하려고합니다. (예, 웹 서비스가 무국적이어야한다는 것을 알고 있습니다. 실제로 지속하려는 것은 세션 ID의 형태이므로 서비스에 대한 모든 호출마다 인증 할 필요가 없습니다). PHP.NET의 API 문서는 이것에 대해 다소 부족하며 그에 대한 다른 것이 많지 않습니다.

나는 그것을 논의하는 한 페이지를 찾았다 (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();

?>

내가 겪는 문제는 $ 이름이 통화 사이에 지속되지 않는다는 것입니다. 나는 항상 setName ()에 할당 할 수있는 값이 아니라 항상 초기화 된 값을 얻습니다. 내가 언급했듯이, 나는 데이터베이스에 대해 인증 한 후 세션 ID를 지속하려고 노력하고 있습니다. 누군가 더 나은 방법이 있다면 나는 제안에 열려 있습니다. 그러나 나는 여전히 일반적인 사례를 해결하고 싶습니다. 누구든지 아이디어가 있습니까?

도움이 되었습니까?

해결책

나는 실제로 내 자신의 문제를 해결했다.

나는 다음과 같은 가정하에 일하고 있었다. 1) .net은 쿠키를 자동으로 처리한다. 그리고 2) 나의 문제는 PHP에 관한 것이었다. 그 경우도 그렇지 않았습니다. 내 PHP 코드는 괜찮 았지만 세션 쿠키를 처리하기 위해 .NET 코드에 요소 하나를 추가해야했습니다.

웹 서비스 객체를 인스턴스화 한 후 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();
        }
    }
}

어쨌든 감사합니다!

다른 팁

대부분의 비누 클라이언트는 각 요청마다 새로운 연결을 시작하므로 "세션"이 없습니다.

SOAP 서비스가 서비스 인 경우 모든 회신에서 SOAP 봉투의 어딘가에 세션 ID를 보내고 모든 후속 요청에서 세션 ID를 전달하도록 클라이언트에게 요청할 수 있습니다.

고객이 이제 Beaviour에 대한 단서와 통제력을 가지고 있기 때문에 이것은 훨씬 좋습니다.

Stateful Web Service를 소비하려면 클라이언트 측의 SOAP 쿠키에서 서버 세션의 세션 ID를 설정해야합니다. SOAP 요청이 전송 될 때마다 기본적으로 서버는 고유 세션 ID를 생성합니다. 이를 방금 설정하지 않기 위해 SOAP 쿠키에서 첫 번째 요청에서 얻은 세션 ID가 발생했습니다. 그 쿠키는 모든 후속 비누 호출과 함께 보내집니다. 예를 들어 SOAP를 사용하여 ASP.NET 웹 서비스를 소비하는 경우 첫 번째 WS 호출 후 다음과 같은 응답 헤더를 얻습니다.

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

지금 $headers 'asp.net_sessionid'와 같은 이름의 세션 ID를 포함해야합니다. ID를 얻으십시오 $headers 다음과 같이 쿠키를 만듭니다.

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

이제 클라이언트의 모든 SOAP 요청에는이 세션 ID가 포함되어 있으며 귀하의 주는 서버에서 지속됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top