Update readme
parent
662b7c4112
commit
81ed82a302
@ -1,22 +1,27 @@
|
|||||||
# webcc
|
# webcc
|
||||||
|
|
||||||
A lightweight C++ REST and SOAP client and server library based on Boost.Asio.
|
A lightweight C++ REST and SOAP client and server library based on *Boost.Asio*.
|
||||||
|
|
||||||
## Tutorials
|
Please see the `doc` folder for tutorials and `example` folder for examples.
|
||||||
|
|
||||||
**SOAP:**
|
## Build Instructions
|
||||||
- [SOAP Client Tutorial](doc/SoapClientTutorial.md)
|
|
||||||
- [SOAP Server Tutorial](doc/SoapServerTutorial.md)
|
|
||||||
|
|
||||||
- [SOAP 客户端教程](doc/SoapClientTutorial_zh-CN.md)
|
A lot of C++11 features are used, e.g., `std::move`. But C++14 is not required. It means that you can still build `webcc` using VS2013.
|
||||||
|
|
||||||
## Dependencies
|
[CMake 3.1.0+](https://cmake.org/) is required as the build system. But if you don't use CMake, you can just copy the `src/webcc` folder to your own project then manage it by yourself.
|
||||||
|
|
||||||
- C++11
|
[C++ Boost](https://www.boost.org/) should be 1.66+ because Asio made some broken changes to the API in 1.66.
|
||||||
- Boost 1.66+
|
|
||||||
|
|
||||||
If enable SOAP support, **pugixml** is needed to parse and compose XML strings.
|
### Build Options
|
||||||
|
|
||||||
## Build
|
The following CMake options determine how you build the projects. They are quite self-explanatory.
|
||||||
|
|
||||||
The build system is CMake.
|
```cmake
|
||||||
|
option(WEBCC_ENABLE_LOG "Enable console logger?" ON)
|
||||||
|
option(WEBCC_ENABLE_SOAP "Enable SOAP support (need pugixml)?" ON)
|
||||||
|
option(WEBCC_BUILD_UNITTEST "Build unit test?" ON)
|
||||||
|
option(WEBCC_BUILD_REST_EXAMPLE "Build REST example?" ON)
|
||||||
|
option(WEBCC_BUILD_SOAP_EXAMPLE "Build SOAP example?" ON)
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WEBCC_ENABLE_SOAP` is `ON`, **pugixml** (already included) is used to parse and compose XML strings.
|
||||||
|
@ -1,36 +1,94 @@
|
|||||||
#include "calc_service.h"
|
#include "calc_service.h"
|
||||||
|
|
||||||
|
// Sleep several seconds for the client to test timeout control.
|
||||||
|
#define SLEEP_FOR_TIMEOUT_TEST 0
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
#include "boost/lexical_cast.hpp"
|
||||||
|
|
||||||
|
#if SLEEP_FOR_TIMEOUT_TEST
|
||||||
|
#include "boost/thread/thread.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "webcc/logger.h"
|
||||||
#include "webcc/soap_request.h"
|
#include "webcc/soap_request.h"
|
||||||
#include "webcc/soap_response.h"
|
#include "webcc/soap_response.h"
|
||||||
|
|
||||||
|
#if SLEEP_FOR_TIMEOUT_TEST
|
||||||
|
static const int kSleepSeconds = 3;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool CalcService::Handle(const webcc::SoapRequest& soap_request,
|
bool CalcService::Handle(const webcc::SoapRequest& soap_request,
|
||||||
webcc::SoapResponse* soap_response) {
|
webcc::SoapResponse* soap_response) {
|
||||||
try {
|
double x = 0.0;
|
||||||
if (soap_request.operation() == "add") {
|
double y = 0.0;
|
||||||
double x = boost::lexical_cast<double>(soap_request.GetParameter("x"));
|
if (!GetParameters(soap_request, &x, &y)) {
|
||||||
double y = boost::lexical_cast<double>(soap_request.GetParameter("y"));
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& op = soap_request.operation();
|
||||||
|
|
||||||
double result = x + y;
|
LOG_INFO("Soap operation '%s': %.2f, %.2f", op.c_str(), x, y);
|
||||||
|
|
||||||
soap_response->set_soapenv_ns(webcc::kSoapEnvNamespace);
|
std::function<double(double, double)> calc;
|
||||||
soap_response->set_service_ns({
|
|
||||||
"cal",
|
|
||||||
"http://www.example.com/calculator/"
|
|
||||||
});
|
|
||||||
soap_response->set_operation(soap_request.operation());
|
|
||||||
soap_response->set_result_name("Result");
|
|
||||||
soap_response->set_result(std::to_string(result));
|
|
||||||
|
|
||||||
return true;
|
if (op == "add") {
|
||||||
|
calc = [](double x, double y) { return x + y; };
|
||||||
|
|
||||||
} else {
|
} else if (op == "subtract") {
|
||||||
// NOT_IMPLEMENTED
|
calc = [](double x, double y) { return x - y; };
|
||||||
|
|
||||||
|
} else if (op == "multiply") {
|
||||||
|
calc = [](double x, double y) { return x * y; };
|
||||||
|
|
||||||
|
} else if (op == "divide") {
|
||||||
|
calc = [](double x, double y) { return x / y; };
|
||||||
|
|
||||||
|
if (y == 0.0) {
|
||||||
|
LOG_ERRO("Cannot divide by 0.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (boost::bad_lexical_cast&) {
|
} else {
|
||||||
// BAD_REQUEST
|
LOG_ERRO("Operation '%s' is not supported.", op.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!calc) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double result = calc(x, y);
|
||||||
|
|
||||||
|
soap_response->set_soapenv_ns(webcc::kSoapEnvNamespace);
|
||||||
|
soap_response->set_service_ns({
|
||||||
|
"cal",
|
||||||
|
"http://www.example.com/calculator/"
|
||||||
|
});
|
||||||
|
|
||||||
|
soap_response->set_operation(soap_request.operation());
|
||||||
|
|
||||||
|
soap_response->set_result_name("Result");
|
||||||
|
soap_response->set_result(std::to_string(result));
|
||||||
|
|
||||||
|
#if SLEEP_FOR_TIMEOUT_TEST
|
||||||
|
LOG_INFO("Sleep %d seconds for the client to test timeout control.",
|
||||||
|
kSleepSeconds);
|
||||||
|
boost::this_thread::sleep_for(boost::chrono::seconds(kSleepSeconds));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalcService::GetParameters(const webcc::SoapRequest& soap_request,
|
||||||
|
double* x,
|
||||||
|
double* y) {
|
||||||
|
try {
|
||||||
|
*x = boost::lexical_cast<double>(soap_request.GetParameter("x"));
|
||||||
|
*y = boost::lexical_cast<double>(soap_request.GetParameter("y"));
|
||||||
|
|
||||||
|
} catch (boost::bad_lexical_cast& e) {
|
||||||
|
LOG_ERRO("Parameter cast error: %s", e.what());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue