Forum Discussion
albert_forster_
Nimbostratus
Feb 02, 2005persistence with rtsp
we are trying to enable persistence based on a universal persistence profile using an irule for rtsp connections.
we have multiple helix servers installed and when accessing video strea...
Mark_Crosland_1
Feb 03, 2005Historic F5 Account
Real-Networks can tunnel RTSP through HTTP. They use the URI /SmpDsBhgRl to
do so. There are two scenarios.
1) There is one POST and one GET.
2) There are multiple POSTs and one GET.
The player will do one or the other based on whether a timely response is
received to the first POST. The following rule will work in either case.
If you want to load balance based on the URI in the RTSP URI you need to
force the second scenario. In the first scenario they send a bogus
content length, 32767, and trying to HTTP::collect it all will cause
enough of a delay (really imperceptible to the user) to force the second
scenario where each POST contains a content length that matches what
they send. The 32767 content-length isn't really bogus, it is just that
they never actually send that much data.
The HTTP POST commands are used by the client to send base64 encoded RTSP
commands. That is why you don't see the RTSP methods, they have been
encoded.
The single HTTP GET command is used as a virtual channel to stream the
audio/video back to the client.
The first 36 bytes of content in each POST contain a session identifier. If
you see /SmpDsBhgRl in a POST URI, collect the 36 bytes of data. When the
36 bytes of data arrives the HTTP_REQUEST_DATA event is fired. Use
HTTP::payload to get the session ID and then persist it.
The rule below will also decode the tunnelled RTSP requests and find the
URI in the DESCRIBE request (typically the first request that contains
a URI). You can then use the uri variable to make further load balancing
decisions.
when HTTP_REQUEST {
set decode_rtsp 0
if { [HTTP::method] eq "POST" && [HTTP::uri] eq "/SmpDsBhgRl" } {
if { [HTTP::header exists "Content-Length"] } {
set clen [HTTP::header value "Content-Length"]
if { $clen == 32767 } {
force multi-post mode, 32767 bytes are never sent
HTTP::collect $clen
or just collect the session ID, however, the player
may choose to go into multi-post mode anyway
HTTP::collect 36
} else {
set decode_rtsp 1
HTTP::collect $clen
}
}
} elseif { [HTTP::method] eq "GET" } {
set uri [HTTP::uri]
if { [string compare -length 11 "/SmpDsBhgRl" $uri] == 0 } {
set session_id [string range $uri 11 end]
persist universal $session_id
}
}
}
when HTTP_REQUEST_DATA {
set content [HTTP::payload]
set session_id [string range $content 0 35]
set decode_idx [expr $clen - 2]
persist universal $session_id
if { $decode_rtsp } {
set rtsp_request [b64decode [string range $content 38 $decode_idx]]
if { [string compare -length 8 $rtsp_request "DESCRIBE"] == 0 } {
set end_of_uri [string first " RTSP/1.0" $rtsp_request]
set uri [string range $rtsp_request 9 $end_of_uri]
now you can dig into the "real" URI to load balance to
specific nodes based on the presentation or to persist
}
set decode_rtsp 0
}
HTTP::release
}
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects