Ejemplo n.º 1
0
bool TransportPublisherLink::initialize(const ConnectionPtr& connection)
{
  connection_ = connection;
  connection_->addDropListener(boost::bind(&TransportPublisherLink::onConnectionDropped, this, _1, _2));

  if (connection_->getTransport()->requiresHeader())
  {
    connection_->setHeaderReceivedCallback(boost::bind(&TransportPublisherLink::onHeaderReceived, this, _1, _2));

    SubscriptionPtr parent = parent_.lock();

    M_string header;
    header["topic"] = parent->getName();
    header["md5sum"] = parent->md5sum();
    header["callerid"] = this_node::getName();
    header["type"] = parent->datatype();
    header["tcp_nodelay"] = transport_hints_.getTCPNoDelay() ? "1" : "0";
    connection_->writeHeader(header, boost::bind(&TransportPublisherLink::onHeaderWritten, this, _1));
  }
  else
  {
    connection_->read(4, boost::bind(&TransportPublisherLink::onMessageLength, this, _1, _2, _3, _4));
  }

  return true;
}
Ejemplo n.º 2
0
void TransportPublisherLink::onRetryTimer(const ros::WallTimerEvent&)
{
  if (dropping_)
  {
    return;
  }

  if (needs_retry_ && WallTime::now() > next_retry_)
  {
    retry_period_ = std::min(retry_period_ * 2, WallDuration(20));
    needs_retry_ = false;
    SubscriptionPtr parent = parent_.lock();
    // TODO: support retry on more than just TCP
    // For now, since UDP does not have a heartbeat, we do not attempt to retry
    // UDP connections since an error there likely means some invalid operation has
    // happened.
    if (connection_->getTransport()->getType() == std::string("TCPROS"))
    {
      std::string topic = parent ? parent->getName() : "unknown";

      TransportTCPPtr old_transport = boost::dynamic_pointer_cast<TransportTCP>(connection_->getTransport());
      ROS_ASSERT(old_transport);
      const std::string& host = old_transport->getConnectedHost();
      int port = old_transport->getConnectedPort();

      ROSCPP_LOG_DEBUG("Retrying connection to [%s:%d] for topic [%s]", host.c_str(), port, topic.c_str());

      TransportTCPPtr transport(new TransportTCP(&PollManager::instance()->getPollSet()));
      if (transport->connect(host, port))
      {
        ConnectionPtr connection(new Connection);
        connection->initialize(transport, false, HeaderReceivedFunc());
        initialize(connection);

        ConnectionManager::instance()->addConnection(connection);
      }
      else
      {
        ROSCPP_LOG_DEBUG("connect() failed when retrying connection to [%s:%d] for topic [%s]", host.c_str(), port, topic.c_str());
      }
    }
    else if (parent)
    {
      parent->removePublisherLink(shared_from_this());
    }
  }
}
void IntraProcessPublisherLink::setPublisher(const IntraProcessSubscriberLinkPtr& publisher)
{
  publisher_ = publisher;

  SubscriptionPtr parent = parent_.lock();
  ROS_ASSERT(parent);

  Header header;
  M_stringPtr values = header.getValues();
  (*values)["callerid"] = this_node::getName();
  (*values)["topic"] = parent->getName();
  (*values)["type"] = publisher->getDataType();
  (*values)["md5sum"] = publisher->getMD5Sum();
  (*values)["message_definition"] = publisher->getMessageDefinition();
  (*values)["latching"] = publisher->isLatching() ? "1" : "0";
  setHeader(header);
}
Ejemplo n.º 4
0
void TransportPublisherLink::onConnectionDropped(const ConnectionPtr& conn, Connection::DropReason reason)
{
  if (dropping_)
  {
    return;
  }

  ROS_ASSERT(conn == connection_);

  SubscriptionPtr parent = parent_.lock();

  if (reason == Connection::TransportDisconnect)
  {
    std::string topic = parent ? parent->getName() : "unknown";

    ROSCPP_LOG_DEBUG("Connection to publisher [%s] to topic [%s] dropped", connection_->getTransport()->getTransportInfo().c_str(), topic.c_str());

    ROS_ASSERT(!needs_retry_);
    needs_retry_ = true;
    next_retry_ = WallTime::now() + retry_period_;

    if (retry_timer_handle_ == -1)
    {
      retry_period_ = WallDuration(0.1);
      next_retry_ = WallTime::now() + retry_period_;
      retry_timer_handle_ = getInternalTimerManager()->add(WallDuration(retry_period_),
          boost::bind(&TransportPublisherLink::onRetryTimer, this, _1), getInternalCallbackQueue().get(),
          VoidConstPtr(), false);
    }
    else
    {
      getInternalTimerManager()->setPeriod(retry_timer_handle_, retry_period_);
    }
  }
  else
  {
    drop();
  }
}