mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #369, support RTMP 302 api at protocol level.
This commit is contained in:
parent
f1e7e9d933
commit
d24aef50ba
7 changed files with 86 additions and 3 deletions
Binary file not shown.
|
@ -137,7 +137,7 @@ package
|
|||
var ms:NetStream = this.media_stream;
|
||||
|
||||
if (!ms) {
|
||||
log("stream is null, ignore timer event.");
|
||||
//log("stream is null, ignore timer event.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -396,6 +396,26 @@ package
|
|||
update_context_items();
|
||||
}
|
||||
|
||||
// reject by server, maybe redirect.
|
||||
if (evt.info.code == "NetConnection.Connect.Rejected") {
|
||||
// RTMP 302 redirect.
|
||||
if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) {
|
||||
var streamName:String = url.substr(url.lastIndexOf("/") + 1);
|
||||
url = evt.info.ex.redirect + "/" + streamName;
|
||||
log("Async RTMP 302 Redirect to: " + url);
|
||||
|
||||
// notify server.
|
||||
media_conn.call("Redirected", null, evt.info.ex.redirect);
|
||||
|
||||
// do 302.
|
||||
setTimeout(function(){
|
||||
log("Async RTMP 302 Redirected.");
|
||||
js_call_play(url, _width, _height, buffer_time, max_buffer_time, volume);
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIXME: failed event.
|
||||
if (evt.info.code != "NetConnection.Connect.Success") {
|
||||
return;
|
||||
|
|
|
@ -26,7 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
bool srs_is_system_control_error(int error_code)
|
||||
{
|
||||
return error_code == ERROR_CONTROL_RTMP_CLOSE
|
||||
|| error_code == ERROR_CONTROL_REPUBLISH;
|
||||
|| error_code == ERROR_CONTROL_REPUBLISH
|
||||
|| error_code == ERROR_CONTROL_REDIRECT;
|
||||
}
|
||||
|
||||
bool srs_is_client_gracefully_close(int error_code)
|
||||
|
|
|
@ -161,6 +161,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
//
|
||||
// system control message,
|
||||
// not an error, but special control logic.
|
||||
//
|
||||
// connection is redirect to another server.
|
||||
#define ERROR_CONTROL_REDIRECT 2997
|
||||
// sys ctl: rtmp close stream, support replay.
|
||||
#define ERROR_CONTROL_RTMP_CLOSE 2998
|
||||
// FMLE stop publish and republish.
|
||||
|
|
|
@ -306,7 +306,9 @@ string srs_generate_rtmp_url(string server, int port, string vhost, string app,
|
|||
ss << "...vhost..." << vhost;
|
||||
}
|
||||
|
||||
ss << "/" << stream;
|
||||
if (!stream.empty()) {
|
||||
ss << "/" << stream;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
@ -2575,6 +2575,57 @@ int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define SRS_RTMP_REDIRECT_TIMEOUT 3000
|
||||
int SrsRtmpServer::redirect(SrsRequest* r, string host, int port, bool& accepted)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if (true) {
|
||||
string url = srs_generate_rtmp_url(host, port, r->vhost, r->app, "");
|
||||
|
||||
SrsAmf0Object* ex = SrsAmf0Any::object();
|
||||
ex->set("code", SrsAmf0Any::number(302));
|
||||
ex->set("redirect", SrsAmf0Any::str(url.c_str()));
|
||||
|
||||
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
|
||||
|
||||
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelError));
|
||||
pkt->data->set(StatusCode, SrsAmf0Any::str(StatusCodeConnectRejected));
|
||||
pkt->data->set(StatusDescription, SrsAmf0Any::str("RTMP 302 Redirect"));
|
||||
pkt->data->set("ex", ex);
|
||||
|
||||
if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send redirect/rejected message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("send redirect/rejected message success.");
|
||||
}
|
||||
|
||||
// client must response a call message.
|
||||
// or we never know whether the client is ok to redirect.
|
||||
protocol->set_recv_timeout(SRS_RTMP_REDIRECT_TIMEOUT * 1000);
|
||||
if (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
SrsCallPacket* pkt = NULL;
|
||||
if ((ret = expect_message<SrsCallPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
||||
// ignore any error of redirect response.
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
SrsAutoFree(SrsCallPacket, pkt);
|
||||
|
||||
string message;
|
||||
if (pkt->arguments && pkt->arguments->is_string()) {
|
||||
message = pkt->arguments->to_str();
|
||||
srs_info("confirm redirected to %s", message.c_str());
|
||||
accepted = true;
|
||||
}
|
||||
srs_info("get redirect response message");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SrsRtmpServer::response_connect_reject(SrsRequest* /*req*/, const char* desc)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -929,6 +929,12 @@ public:
|
|||
* @param server_ip the ip of server.
|
||||
*/
|
||||
virtual int response_connect_app(SrsRequest* req, const char* server_ip = NULL);
|
||||
/**
|
||||
* redirect the connection to another rtmp server.
|
||||
* @param the hostname or ip of target.
|
||||
* @param whether the client accept the redirect.
|
||||
*/
|
||||
virtual int redirect(SrsRequest* r, std::string host, int port, bool& accepted);
|
||||
/**
|
||||
* reject the connect app request.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue