This is an old revision of the document!


Using Synapse In A Borland SOAP Client

From: Stig Johansen (stig.johansen@udvikling.it)
Subject: Re: Cannot run two SOAP-threads ?
Newsgroups: borland.public.kylix.internet.web
Date: 2002-05-06 21:01:50 PST

Jochen Staerk wrote:

i've got a problem that my kylix raises several errors up to sigservs
when i try to run two or more threads that create themselves httprios
and query a web service. the same code runs with windows!

I had the some problems using soap clients in multithreaded environments. I have a working solution, allthough I am not sure whether it is the right solution:

  • In oxmldom.pas, the handling of GlobalOXDOM is not threadsafe. I changes the declaration to threadvar instead of var.
  • The indy components. In my project, when using small packets, the first request is ok, the second inserts extra crlf in the header, the third crashes. I dont have the time to debug indy, so I replaced it with Synapse.

See: From my previous post:

I downloaded the latest source, and made the following changes in SOAPHTTPTrans:

Added:

  procedure SetupSyna(SynaHttp: THTTPSend);
  var
    ContentHeader, ActionHeader: string;
    Protocol, Host, path, Document, Port, Bookmark: string;
  begin
    if (soNoValueForEmptySOAPAction in FInvokeOptions) and (SoapAction = 
'') then
      ActionHeader := SHTTPSoapAction + ':'
    else if SoapAction = '""' then
      ActionHeader := SHTTPSoapAction + ': ""'
    else
      ActionHeader := SHTTPSoapAction + ': ' + '"' + FSoapAction + '"';
    SynaHttp.Headers.Add(ActionHeader);
    SynaHTTP.MimeType := 'text/xml';   { do not localize }
    SynaHttp.Protocol := '1.0' ;
  end;
 
{$IFDEF USE_SYNA}
  procedure PostData(Response: TStream);
  var
    SynaHTTP: THTTPSend;
    WireData: string;
  begin
    SynaHTTP := THTTPSend.Create;
    try
      SetupSyna(SynaHttp);
      WireData := UTF8Encode(DataMsg);
      SynaHTTP.Document.Write(Pointer(WireData)^, Length(WireData));
      try
      SynaHTTP.HTTPMethod('POST', FURL);
      Response.CopyFrom(SynaHTTP.Document, 0);
      finally
      end;
    finally
      FreeAndNil(SynaHTTP);
    end;
  end;
{$ENDIF}
 
And the following change:
{$IFDEF USE_INDY}
    InitURL(FURL);
{$ENDIF}

Delphi 7

Changes to do in SOAPHTTPTrans in order to use synapase
 
You should add synapse in the same way Indy is used.
 
-- define USE_SYNA:
 
{$IFDEF LINUX}
//{$DEFINE USE_INDY}
{$DEFINE USE_SYNA}
{$ENDIF}
{$IFDEF MSWINDOWS}
//{$DEFINE USE_INDY}
{$DEFINE USE_SYNA}
{$ENDIF}
 
-- in uses:
uses ... ,
{$IFDEF USE_SYNA}
HTTPSend, synautil;
{$ELSE}
{$IFDEF USE_INDY}
...;
{$ELSE}
  ...;
{$ENDIF}
{$ENDIF}
 
-- Search for USE_INDY
and add {$IFNDEF USE_SYNA} as for {$IFNDEF USE_INDY}
e.g:
{$IFNDEF USE_SYNA}
{$IFNDEF USE_INDY}
    ...
    ...
{$ELSE}
    ...
{$ENDIF}
{$ENDIF}
 
 
-- in THTTPReqResp.Execute add:
 
{$IFDEF USE_SYNA}
  procedure SetupSyna(SynaHttp: THTTPSend);
  var
    ActionHeader: string;
    Protocol, Host, Path, Port, Para, pUser, pPass: string;
  begin
    if (soNoValueForEmptySOAPAction in FInvokeOptions) and (SoapAction = '') then
      ActionHeader := SHTTPSoapAction + ':'
    else if SoapAction = '""' then
      ActionHeader := SHTTPSoapAction + ': ""'
    else
      ActionHeader := SHTTPSoapAction + ': ' + '"' + FSoapAction + '"';
 
    SynaHttp.UserName := FUserName;
    SynaHttp.Password := FPassword;
 
    if FProxy <> '' then
    begin
      ParseURL(FProxy, Protocol, pUser, pPass, Host, Port, Path, Para);
      SynaHttp.ProxyHost := Host;
      SynaHttp.ProxyPort := Port;
      SynaHttp.ProxyUser := pUser;
      SynaHttp.ProxyPass := pPass;
    end;
    SynaHttp.Headers.Add(ActionHeader);
    SynaHttp.MimeType := 'text/xml';   { do not localize }
    SynaHttp.Protocol := '1.0' ;
    SynaHttp.UserAgent := Self.FAgent;
  end;
 
 
  procedure PostData(const Request: TStream; Response: TStream);
  var
    SynaHTTP: THTTPSend;
  begin
    SynaHTTP := THTTPSend.Create;
    try
      SetupSyna(SynaHttp);
 
      Request.Position := 0;
      SynaHTTP.Document.LoadFromStream(Request);
      SynaHTTP.Document.Position := 0;
      try
        if SynaHTTP.HTTPMethod('POST', FURL) then
          Response.CopyFrom(SynaHTTP.Document, 0)
        else
          raise ESOAPHTTPException.Create(SInvalidHTTPResponse);        
      finally
      end;
    finally
      FreeAndNil(SynaHTTP);
    end;
  end;
{$ENDIF}
 
-- then change:
 
{$IFDEF USE_INDY}
  PostData(Request, Response);
{$ELSE}
  ...
{$ENDIF}
 
-- with
 
{$IFDEF USE_SYNA}
  PostData(Request, Response);
{$ELSE}
{$IFDEF USE_INDY}
  PostData(Request, Response);
{$ELSE}
    ...
{$ENDIF}
{$ENDIF}
public/howto/synapsesoap.1238412238.txt.gz · Last modified: 2009/03/30 13:23 by tibard
Driven by DokuWiki Recent changes RSS feed