-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNetel.Soap.NLRIO.pas
152 lines (115 loc) · 3.99 KB
/
Netel.Soap.NLRIO.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
unit Netel.Soap.NLRIO;
{-------------------------------------------------------------------------------
这是封装了 TLinkedRIO 的作为 RIO 客户端的一个 RIO
TNLRioClient 对象通过事件输出SOAP请求数据,然后阻塞;外界通过调用它的公共方法输入 SOAP 应答,然后给信号。
pcplayer 2007-8-14
-------------------------------------------------------------------------------}
interface
uses Classes, SysUtils, Rio, TypInfo, WebNode, SOAPPasInv, IntfInfo, WSDLIntf, SyncObjs,
SOAPAttachIntf, Soap.SOAPLinked;
type
TNLRioRequestEvent = procedure(Sender: TObject; Request: TStream) of object;
//add by pcplayer 2022-5-19
TNLClientLinkedWebNode = class(TLinkedWebNode)
private
FOnRequestEvent: TOnRequestEvent;
public
procedure Execute(const Request: TStream; Response: TStream); override;
published
property NLOnRequestEvent: TOnRequestEvent read FOnRequestEvent write FOnRequestEvent;
end;
TNLRio = class(TLinkedRIO)
public
constructor CreateNetel(AOwner: TComponent; OnRequestEvent: TOnRequestEvent); overload;
end;
TNLRioClient = class(TNLRio) // class(TLinkedRIO) //
private
FEvent: TSimpleEvent;
FStream: TStream;
FOnRequestEvent: TNLRioRequestEvent;
procedure DoOnRequest(Request, Response: TStream);
public
constructor Create;
destructor Destroy; override;
procedure WriteSoapResponse(Response: TStream); overload;
procedure ResetEvent;
property NLOnRioRequest: TNLRioRequestEvent read FOnRequestEvent write FOnRequestEvent;
end;
TNLRioServer = class(TLinkedRIO)
private
public
procedure Execute(const Request: TStream; Response: TStream);
end;
implementation
uses Soap.OPConvert;
{ TNLRioClient }
constructor TNLRioClient.Create;
begin
FEvent := TSimpleEvent.Create;
FEvent.ResetEvent;
inherited CreateNetel(nil, DoOnRequest);
end;
destructor TNLRioClient.Destroy;
begin
//FEvent.ResetEvent;
FEvent.Free;
inherited;
end;
procedure TNLRioClient.DoOnRequest(Request, Response: TStream);
begin
{-------------------------------------------------------------------------
作为 SOAP 客户端的 RIO 在这里输出 Request,等待输入 Response
在这个事件里,把两个 Stream 都送给外界,一个拿去发送,一个让外界把收到的数据填进去。
所以,这里要做的事仅仅是产生一个事件,然后等待。因此这个类仅仅是起到阻塞的作用。
---------------------------------------------------------------------------}
FStream := Response;
if Assigned(FOnRequestEvent) then FOnRequestEvent(Self, Request);
FEvent.WaitFor(120000); //2分钟,对于大型应用,可能需要改为5分钟甚至10分钟。
FEvent.ResetEvent;
//if Resp.Size = 0 then raise Exception.Create('SOAP 请求没有获得应答。');
end;
procedure TNLRioClient.ResetEvent;
begin
try
if Assigned(FEvent) then
begin
FEvent.SetEvent;
FEvent.ResetEvent;
end;
except
end;
end;
procedure TNLRioClient.WriteSOAPResponse(Response: TStream);
begin
Response.Position := 0;
FStream.Position := 0;
FStream.CopyFrom(Response, Response.Size);
FEvent.SetEvent;
//FEvent.ResetEvent;
end;
{ TNLClientLinkedWebNode }
procedure TNLClientLinkedWebNode.Execute(const Request: TStream;
Response: TStream);
begin
if Assigned(FOnRequestEvent) then FOnRequestEvent(Request, Response);
end;
{ TNLRio }
constructor TNLRio.CreateNetel(AOwner: TComponent;
OnRequestEvent: TOnRequestEvent);
begin
inherited Create(nil);
if Assigned(FLinkedWebNode) then FLinkedWebNode.Free;
Self.FLinkedWebNode := TNLClientLinkedWebNode.Create(nil);
TNLClientLinkedWebNode(FLinkedWebNode).NLOnRequestEvent := OnRequestEvent;
FLinkedWebNode.IntfInfo := IntfMD.Info;
FWebNode := FLinkedWebNode as IWebNode;
{ Converter }
FDOMConverter := GetDefaultConverter;
FConverter := FDOMConverter as IOPConvert;
end;
{ TNLRioServer }
procedure TNLRioServer.Execute(const Request: TStream; Response: TStream);
begin
Self.FLinkedWebNode.Execute(Request, Response);
end;
end.