int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server) { int ret = ERROR_SUCCESS; // forward app app = req->app; stream_name = req->stream; server = forward_server; std::string s_port = RTMP_DEFAULT_PORT; port = ::atoi(RTMP_DEFAULT_PORT); size_t pos = forward_server.find(":"); if (pos != std::string::npos) { s_port = forward_server.substr(pos + 1); server = forward_server.substr(0, pos); } // discovery vhost std::string vhost = req->vhost; srs_vhost_resolve(vhost, s_port); port = ::atoi(s_port.c_str()); // generate tcUrl tc_url = "rtmp://"; tc_url += vhost; tc_url += "/"; tc_url += req->app; // dead loop check std::string source_ep = req->vhost; source_ep += ":"; source_ep += req->port; std::string dest_ep = vhost; dest_ep += ":"; dest_ep += s_port; if (source_ep == dest_ep) { ret = ERROR_SYSTEM_FORWARD_LOOP; srs_warn("farder loop detected. src=%s, dest=%s, ret=%d", source_ep.c_str(), dest_ep.c_str(), ret); return ret; } srs_trace("start forward %s to %s, stream: %s/%s", source_ep.c_str(), dest_ep.c_str(), tc_url.c_str(), stream_name.c_str()); if ((ret = pthread->start()) != ERROR_SUCCESS) { srs_error("start srs thread failed. ret=%d", ret); return ret; } return ret; }
int SrsRequest::discovery_app() { int ret = ERROR_SUCCESS; size_t pos = std::string::npos; std::string url = tcUrl; if ((pos = url.find("://")) != std::string::npos) { schema = url.substr(0, pos); url = url.substr(schema.length() + 3); srs_verbose("discovery schema=%s", schema.c_str()); } if ((pos = url.find("/")) != std::string::npos) { vhost = url.substr(0, pos); url = url.substr(vhost.length() + 1); srs_verbose("discovery vhost=%s", vhost.c_str()); } port = RTMP_DEFAULT_PORTS; if ((pos = vhost.find(":")) != std::string::npos) { port = vhost.substr(pos + 1); vhost = vhost.substr(0, pos); srs_verbose("discovery vhost=%s, port=%s", vhost.c_str(), port.c_str()); } app = url; srs_vhost_resolve(vhost, app); // resolve the vhost from config SrsConfDirective* parsed_vhost = config->get_vhost(vhost); if (parsed_vhost) { vhost = parsed_vhost->arg0(); } srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s", schema.c_str(), vhost.c_str(), port.c_str(), app.c_str()); if (schema.empty() || vhost.empty() || port.empty() || app.empty()) { ret = ERROR_RTMP_REQ_TCURL; srs_error("discovery tcUrl failed. " "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d", tcUrl.c_str(), schema.c_str(), vhost.c_str(), port.c_str(), app.c_str(), ret); return ret; } strip(); return ret; }
int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server) { int ret = ERROR_SUCCESS; // forward app app = req->app; stream_name = req->stream; server = forward_server; std::string s_port = RTMP_DEFAULT_PORT; port = ::atoi(RTMP_DEFAULT_PORT); // TODO: FIXME: parse complex params size_t pos = forward_server.find(":"); if (pos != std::string::npos) { s_port = forward_server.substr(pos + 1); server = forward_server.substr(0, pos); } // discovery vhost std::string vhost = req->vhost; srs_vhost_resolve(vhost, s_port); port = ::atoi(s_port.c_str()); // generate tcUrl tc_url = "rtmp://"; if (vhost == RTMP_VHOST_DEFAULT) { tc_url += forward_server; } else { tc_url += vhost; } tc_url += "/"; tc_url += req->app; // dead loop check std::string source_ep = "rtmp://"; source_ep += req->host; source_ep += ":"; source_ep += req->port; source_ep += "?vhost="; source_ep += req->vhost; std::string dest_ep = "rtmp://"; if (forward_server == "127.0.0.1") { dest_ep += req->host; } else { dest_ep += forward_server; } dest_ep += ":"; dest_ep += s_port; dest_ep += "?vhost="; dest_ep += vhost; if (source_ep == dest_ep) { ret = ERROR_SYSTEM_FORWARD_LOOP; srs_warn("forward loop detected. src=%s, dest=%s, ret=%d", source_ep.c_str(), dest_ep.c_str(), ret); return ret; } srs_trace("start forward %s to %s, tcUrl=%s, stream=%s", source_ep.c_str(), dest_ep.c_str(), tc_url.c_str(), stream_name.c_str()); if ((ret = pthread->start()) != ERROR_SUCCESS) { srs_error("start srs thread failed. ret=%d", ret); return ret; } srs_trace("forward thread cid=%d, current_cid=%d", pthread->cid(), _srs_context->get_id()); return ret; }