server.cpp 3.48 KB
Newer Older
1
#include "server.h"
2

3 4
#include "rapidjson/include/rapidjson/ostreamwrapper.h"

Valentin Platzgummer's avatar
Valentin Platzgummer committed
5
ros_bridge::com_private::Server::Server(RosbridgeWsClient &rbc) :
6
    _rbc(rbc)
7
  , _stopped(std::make_shared<std::atomic_bool>(true))
8 9 10 11
{

}

12
void ros_bridge::com_private::Server::advertiseService(const std::string &service,
13 14 15 16
                                                     const std::string &type,
                                                     const Server::CallbackType &userCallback)
{
    std::string clientName = _serviceAdvertiserKey + service;
17 18
    auto it = _serviceMap.find(clientName);
    if (it != _serviceMap.end())
19
        return; // Service allready advertised.
20
    _serviceMap.insert(std::make_pair(clientName, service));
21 22 23 24
    _rbc.addClient(clientName);

    auto rbc = &_rbc;
    _rbc.advertiseService(clientName, service, type,
Valentin Platzgummer's avatar
Valentin Platzgummer committed
25
                          [userCallback, rbc](
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
                          std::shared_ptr<WsClient::Connection>,
                          std::shared_ptr<WsClient::InMessage> in_message){
        // message->string() is destructive, so we have to buffer it first
        std::string messagebuf = in_message->string();
        //std::cout << "advertiseServiceCallback(): Message Received: "
                 // << messagebuf << std::endl;

        rapidjson::Document document;
        if (document.Parse(messagebuf.c_str()).HasParseError())
        {
          std::cerr << "advertiseServiceCallback(): Error in parsing service request message: "
                    << messagebuf << std::endl;
          return;
        }

        if ( !document.HasMember("args") || !document["args"].IsObject()){
42 43 44 45 46 47 48 49 50 51 52 53 54
            std::cerr << "advertiseServiceCallback(): message has no args member: "
                      << messagebuf << std::endl;
            return;
        }

        if ( !document.HasMember("service") || !document["service"].IsString()){
            std::cerr << "advertiseServiceCallback(): message has no service member: "
                      << messagebuf << std::endl;
            return;
        }

        if ( !document.HasMember("id") || !document["id"].IsString()){
            std::cerr << "advertiseServiceCallback(): message has no id member: "
55 56 57 58 59 60 61 62 63 64 65 66
                      << messagebuf << std::endl;
            return;
        }
        JsonDocUPtr pDoc(new JsonDoc());
        std::cout << "args member count: " << document["args"].MemberCount();
        if ( document["args"].MemberCount() > 0)
            pDoc->CopyFrom(document["args"].Move(), document.GetAllocator());
        JsonDocUPtr pDocResponse = userCallback(std::move(pDoc));

        rbc->serviceResponse(
                    document["service"].GetString(),
                    document["id"].GetString(),
67
                    pDocResponse->MemberCount() > 0 ? true : false,
68 69 70 71 72 73 74
                    *pDocResponse);

        return;

    });
}

75
ros_bridge::com_private::Server::~Server()
76
{
77 78
    this->reset();
}
79

80
void ros_bridge::com_private::Server::start()
81
{
82
    _stopped->store(false);
83 84
}

85
void ros_bridge::com_private::Server::reset()
86
{
87
    if ( _stopped->load() )
88
        return;
89 90
    std::cout << "Server: _stopped->store(true)" << std::endl;
    _stopped->store(true);
91
    for (const auto& item : _serviceMap){
92
        std::cout << "Server: unadvertiseService " << item.second << std::endl;
93
        _rbc.unadvertiseService(item.second);
94
        std::cout << "Server: removeClient " << item.first << std::endl;
95 96
        _rbc.removeClient(item.first);
    }
97
    std::cout << "Server: _serviceMap cleared " << std::endl;
98
    _serviceMap.clear();
99
}