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

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

Valentin Platzgummer's avatar
Valentin Platzgummer committed
5
static const char *serviceAdvertiserKey = "service_advertiser";
6

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

Valentin Platzgummer's avatar
Valentin Platzgummer committed
10 11 12
void ros_bridge::com_private::Server::advertiseService(
    const std::string &service, const std::string &type,
    const Server::CallbackType &userCallback) {
13

Valentin Platzgummer's avatar
Valentin Platzgummer committed
14 15 16 17 18 19
  std::string clientName = serviceAdvertiserKey + service;
  auto it = _serviceMap.find(clientName);
  if (it != _serviceMap.end())
    return; // Service allready advertised.
  _serviceMap.insert(std::make_pair(clientName, service));
  _rbc.addClient(clientName);
20

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

        rapidjson::Document document;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
32 33 34
        if (document.Parse(messagebuf.c_str()).HasParseError()) {
          std::cerr << "advertiseServiceCallback(): Error in parsing service "
                       "request message: "
35 36 37 38
                    << messagebuf << std::endl;
          return;
        }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
39 40 41 42 43
        if (!document.HasMember("args") || !document["args"].IsObject()) {
          std::cerr
              << "advertiseServiceCallback(): message has no args member: "
              << messagebuf << std::endl;
          return;
44 45
        }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
46 47 48 49 50
        if (!document.HasMember("service") || !document["service"].IsString()) {
          std::cerr
              << "advertiseServiceCallback(): message has no service member: "
              << messagebuf << std::endl;
          return;
51 52
        }

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

        rbc->serviceResponse(
Valentin Platzgummer's avatar
Valentin Platzgummer committed
65 66
            document["service"].GetString(), document["id"].GetString(),
            pDocResponse->MemberCount() > 0 ? true : false, *pDocResponse);
67 68

        return;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
69
      });
70 71
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
72
ros_bridge::com_private::Server::~Server() { this->reset(); }
73

Valentin Platzgummer's avatar
Valentin Platzgummer committed
74
void ros_bridge::com_private::Server::start() { _stopped->store(false); }
75

Valentin Platzgummer's avatar
Valentin Platzgummer committed
76 77 78 79 80 81 82 83 84 85 86 87 88
void ros_bridge::com_private::Server::reset() {
  if (_stopped->load())
    return;
  std::cout << "Server: _stopped->store(true)" << std::endl;
  _stopped->store(true);
  for (const auto &item : _serviceMap) {
    std::cout << "Server: unadvertiseService " << item.second << std::endl;
    _rbc.unadvertiseService(item.second);
    std::cout << "Server: removeClient " << item.first << std::endl;
    _rbc.removeClient(item.first);
  }
  std::cout << "Server: _serviceMap cleared " << std::endl;
  _serviceMap.clear();
89
}