Update the SOAP server tutorial.
This commit is contained in:
+65
-24
@@ -4,25 +4,28 @@ Suppose you want to provide a calculator web service just like the one from [Par
|
|||||||
|
|
||||||
Firstly, create a class `CalcService` which is derived from `webcc::SoapService`, override the `Handle` method:
|
Firstly, create a class `CalcService` which is derived from `webcc::SoapService`, override the `Handle` method:
|
||||||
```cpp
|
```cpp
|
||||||
|
// calc_service.h
|
||||||
|
|
||||||
#include "webcc/soap_service.h"
|
#include "webcc/soap_service.h"
|
||||||
|
|
||||||
class CalcService : public webcc::SoapService {
|
class CalcService : public webcc::SoapService {
|
||||||
public:
|
public:
|
||||||
CalcService() = default;
|
|
||||||
|
|
||||||
bool Handle(const webcc::SoapRequest& soap_request,
|
bool Handle(const webcc::SoapRequest& soap_request,
|
||||||
webcc::SoapResponse* soap_response) override;
|
webcc::SoapResponse* soap_response) override;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
The `Handle` method has two parameters, one for request (input), one for response (output).
|
|
||||||
The implementation is quite straightforward:
|
The `Handle` method has two parameters, one for request (input), one for response (output). The implementation is quite straightforward:
|
||||||
- Get operation from request.
|
|
||||||
- Get parameters from request.
|
- Get operation (e.g., add) from request;
|
||||||
|
- Get parameters (e.g., x and y) from request;
|
||||||
- Calculate the result.
|
- Calculate the result.
|
||||||
- Set namespaces, result name and so on to response.
|
- Set namespaces, result name and so on to response.
|
||||||
- Set result to response.
|
- Set result to response.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
// calc_service.cpp
|
||||||
|
|
||||||
#include "calc_service.h"
|
#include "calc_service.h"
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
#include "boost/lexical_cast.hpp"
|
||||||
@@ -40,36 +43,29 @@ bool CalcService::Handle(const webcc::SoapRequest& soap_request,
|
|||||||
double result = x + y;
|
double result = x + y;
|
||||||
|
|
||||||
soap_response->set_soapenv_ns(webcc::kSoapEnvNamespace);
|
soap_response->set_soapenv_ns(webcc::kSoapEnvNamespace);
|
||||||
soap_response->set_service_ns({
|
soap_response->set_service_ns({ "cal", "http://www.example.com/calculator/" });
|
||||||
"cal",
|
|
||||||
"http://www.example.com/calculator/"
|
|
||||||
});
|
|
||||||
soap_response->set_operation(soap_request.operation());
|
soap_response->set_operation(soap_request.operation());
|
||||||
soap_response->set_result_name("Result");
|
soap_response->set_result_name("Result");
|
||||||
soap_response->set_result(std::to_string(result));
|
soap_response->set_result(std::to_string(result));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
|
||||||
// NOT_IMPLEMENTED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Other operations ...
|
||||||
|
|
||||||
} catch (boost::bad_lexical_cast&) {
|
} catch (boost::bad_lexical_cast&) {
|
||||||
// BAD_REQUEST
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `main` function would be:
|
Next step, create a `SoapServer` and register `CalcService` to it with a URL.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc != 2) {
|
// Check argc and argv ...
|
||||||
std::cout << "Usage: " << argv[0] << " <port>" << std::endl;
|
|
||||||
std::cout << " E.g.," << std::endl;
|
|
||||||
std::cout << " " << argv[0] << " 8080" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short port = std::atoi(argv[1]);
|
unsigned short port = std::atoi(argv[1]);
|
||||||
|
|
||||||
@@ -79,16 +75,61 @@ int main(int argc, char* argv[]) {
|
|||||||
try {
|
try {
|
||||||
webcc::SoapServer server(port, workers);
|
webcc::SoapServer server(port, workers);
|
||||||
|
|
||||||
server.RegisterService(std::make_shared<CalcService>(),
|
server.RegisterService(std::make_shared<CalcService>(), "/calculator");
|
||||||
"/calculator");
|
|
||||||
|
|
||||||
server.Run();
|
server.Run();
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
std::cerr << "exception: " << e.what() << std::endl;
|
std::cerr << "Exception: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The server is created with a **port number** which will be listened on to **asynchnously** accept client connections. The connections will be firstly put into a **queue** and then processed by the **worker threads**. The number of worker threads is determined by the `workers` parameter.
|
||||||
|
|
||||||
|
When register service, the URL is what the clients will put in the HTTP request to access your service:
|
||||||
|
```
|
||||||
|
POST /calculator HTTP/1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Registering multiple services to a server is allowed, but the URL must be unique for each service.
|
||||||
|
|
||||||
|
To invoke the `add` operation of the calculator service, the client HTTP request will be:
|
||||||
|
```
|
||||||
|
POST /calculator HTTP/1.1
|
||||||
|
Content-Type: text/xml; charset=utf-8
|
||||||
|
Content-Length: 263
|
||||||
|
Host: localhost:8080
|
||||||
|
SOAPAction: add
|
||||||
|
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<ser:add xmlns:ser="http://www.example.com/calculator/">
|
||||||
|
<ser:x>1.000000</ser:x>
|
||||||
|
<ser:y>2.000000</ser:y>
|
||||||
|
</ser:add>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
||||||
|
```
|
||||||
|
|
||||||
|
And the HTTP response is:
|
||||||
|
```
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: text/xml; charset=utf-8
|
||||||
|
Content-Length: 262
|
||||||
|
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<cal:addResponse xmlns:cal="http://www.example.com/calculator/">
|
||||||
|
<cal:Result>3.000000</cal:Result>
|
||||||
|
</cal:addResponse>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
||||||
|
```
|
||||||
|
|
||||||
|
See [example/soap_calc_server](example/soap_calc_server) for the full example.
|
||||||
|
|||||||
Reference in New Issue
Block a user