自己调试OK的客户端discovery功能,discovery code
先从remotediscovery.wsdl解析入手吧。可以参考此网页WSDL实例解析 和 一个完整的WSDL文档及各标签详解。
这个非常重要,直接导致是否可以调用到web server的功能函数。
1
|
< wsdl:definitions
xmlns:dn = "http://www.onvif.org/ver10/network/wsdl"
xmlns:wsdl = "http://schemas.xmlsoap.org/wsdl/"
xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
targetNamespace = "http://www.onvif.org/ver10/network/wsdl" > |
targetNamespace="http://www.onvif.org/ver10/network/wsdl",采用的命空间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
< wsdl:types > < xs:schema
targetNamespace = "http://www.onvif.org/ver10/network/wsdl"
xmlns:d = "http://schemas.xmlsoap.org/ws/2005/04/discovery"
elementFormDefault = "qualified" > < xs:import
namespace = "http://schemas.xmlsoap.org/ws/2005/04/discovery"
schemaLocation = "http://schemas.xmlsoap.org/ws/2005/04/discovery/ws-discovery.xsd" /> <!-- Message Request/Responses elements --> <!--===============================--> < xs:element
name = "Hello"
type = "d:HelloType" /> < xs:element
name = "HelloResponse"
type = "d:ResolveType" /> < xs:element
name = "Probe"
type = "d:ProbeType" /> < xs:element
name = "ProbeResponse"
type = "d:ProbeMatchesType" /> < xs:element
name = "Bye"
type = "d:ByeType" /> < xs:element
name = "ByeResponse"
type = "d:ResolveType" /> <!--===============================--> </ xs:schema > </ wsdl:types > |
schemaLocation="http://schemas.xmlsoap.org/ws/2005/04/discovery/ws-discovery.xsd"/,进入/ws-discovery.xsd可以看到
1
2
3
4
5
6
7
8
|
< xs:complexType
name = "ProbeType" > < xs:sequence > < xs:element
ref = "tns:Types"
minOccurs = "0" /> < xs:element
ref = "tns:Scopes"
minOccurs = "0" /> < xs:any
namespace = "##other"
processContents = "lax"
minOccurs = "0"
maxOccurs = "unbounded" /> </ xs:sequence > < xs:anyAttribute
namespace = "##other"
processContents = "lax" /> </xs:complexType |
code中对应的为,命名由 <
xs:element
name
=
"Probe"
type
=
"d:ProbeType"
/>
中的
type
=
"d:ProbeType"
而来
1
2
3
4
5
6
7
8
9
10
11
12
|
#ifndef SOAP_TYPE_d__ProbeType #define SOAP_TYPE_d__ProbeType (290) /* d:ProbeType */ struct
d__ProbeType { char
**Types; /* optional element of type xsd:QName */ struct
d__ScopesType *Scopes; /* optional element of type d:ScopesType */ int
__size; /* sequence of elements <-any> */ char
**__any; char
*__anyAttribute; /* optional attribute of type xsd:anyType */ }; #endif |
1
2
3
4
|
</ wsdl:message > < wsdl:message
name = "ProbeRequest" > < wsdl:part
name = "parameters"
element = "dn:Probe" /> </ wsdl:message > |
<
wsdl:part
name
=
"parameters"
element
=
"dn:Probe"
/>
表明使用的是
<
xs:element
name
=
"Probe"
type
=
"d:ProbeType"
/>,也即为
struct
d__ProbeType。
4、函数体
1
2
3
4
5
6
|
< wsdl:portType
name = "DiscoveryLookupPort" > < wsdl:operation
name = "Probe" > < wsdl:input
message = "dn:ProbeRequest"
dn:Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe" /> < wsdl:output
message = "dn:ProbeResponse"
dn:Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches" /> </ wsdl:operation > </ wsdl:portType > |
这个 dn:Action
=
"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"
望文生义是关于Probe()的,具体
不知道什么意义,也没有找到此页面。知道的同学请告知。
客户端:
SOAP_FMAC5 int SOAP_FMAC6 soap_call___d__Probe(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct d__ProbeType *d__Probe, struct d__ProbeMatchesType *d__ProbeMatches)
此soap_call___d__Probe(和soap_serve___d__Probe交互)可以调用用web server的Probe功能。
服务端:
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
|
/* soap_serve --> soap_serve_request --> soap_serve___d__Probe --> sever_probe */ int
main( int
argc, char
**argv) { int
m, s; struct
soap add_soap; soap_init(&add_soap); soap_set_namespaces(&add_soap, namespaces); if
(argc < 2) { printf ( "usage: %s <server_port> \n" , argv[0]); exit (1); } else
{ m = soap_bind(&add_soap, NULL, atoi (argv[1]), 100); if
(m < 0) { soap_print_fault(&add_soap, stderr); exit (-1); } fprintf (stderr, "Socket connection successful: master socket = %d\n" , m); for
(;;) { s = soap_accept(&add_soap); if
(s < 0) { soap_print_fault(&add_soap, stderr); exit (-1); } fprintf (stderr, "Socket connection successful: slave socket = %d\n" , s); soap_serve(&add_soap); soap_end(&add_soap); } } return
0; } SOAP_FMAC5 int
SOAP_FMAC6 soap_serve( struct
soap *soap) { #ifndef WITH_FASTCGI unsigned int
k = soap->max_keep_alive; #endif do { #ifndef WITH_FASTCGI if
(soap->max_keep_alive > 0 && !--k) soap->keep_alive = 0; #endif if
(soap_begin_serve(soap)) { if
(soap->error >= SOAP_STOP) continue ; return
soap->error; } if
(soap_serve_request(soap) || (soap->fserveloop && soap->fserveloop(soap))) { #ifdef WITH_FASTCGI soap_send_fault(soap); #else return
soap_send_fault(soap); #endif } #ifdef WITH_FASTCGI soap_destroy(soap); soap_end(soap); } while
(1); #else } while
(soap->keep_alive); #endif return
SOAP_OK; } SOAP_FMAC5 int
SOAP_FMAC6 soap_serve_request( struct
soap *soap) { soap_peek_element(soap); if
(!soap_match_tag(soap, soap->tag, "SOAP-ENV:Fault" )) return
soap_serve_SOAP_ENV__Fault(soap); if
(!soap_match_tag(soap, soap->tag, "d:Hello" )) return
soap_serve___d__Hello(soap); if
(!soap_match_tag(soap, soap->tag, "d:Bye" )) return
soap_serve___d__Bye(soap); if
(!soap_match_tag(soap, soap->tag, "d:Probe" )) return
soap_serve___d__Probe(soap); ...... } soap_serve___d__Probe { sever_probe(); } |
5、绑定
这个就是wsdl和soap的结合了。前面的理解没问题的话,这部分就不用关心了。
调通了discovery,只是一个良好的开端。后续还有一堆事情要解决。待续。
?最后采用的代码是soap_send___wsdd__Probe/soap_recv___wsdd__ProbeMatches,空间不同而已。换用soap_send___wsdd__Probe的时候,出了一个小BUG:设定的timeout 似乎对soap_recv___wsdd__ProbeMatches无效。经排查对比,发现是gsoap版本的差异。
1
2
3
4
5
6
7
8
9 |
while
(result == SOAP_OK) { //gsoap2.8.17 block, gsoap2.8.1.10 timeout enable result = soap_recv___wsdd__ProbeMatches(psoap, &res); } |
原文:http://www.cnblogs.com/freezlz/p/3561324.html