Allow HTTP Connector to reconnect to different buffers - closes #31
This commit is contained in:
parent
a08f8e3033
commit
98cde39a8f
3 changed files with 70 additions and 33 deletions
|
@ -53,13 +53,16 @@ void Socket::Connection::setBlocking(bool blocking){
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close connection. The internal socket is closed and then set to -1.
|
/// Close connection. The internal socket is closed and then set to -1.
|
||||||
|
/// If the connection is already closed, nothing happens.
|
||||||
void Socket::Connection::close(){
|
void Socket::Connection::close(){
|
||||||
#if DEBUG >= 6
|
if (connected()){
|
||||||
fprintf(stderr, "Socket closed.\n");
|
#if DEBUG >= 6
|
||||||
#endif
|
fprintf(stderr, "Socket closed.\n");
|
||||||
shutdown(sock, SHUT_RDWR);
|
#endif
|
||||||
::close(sock);
|
shutdown(sock, SHUT_RDWR);
|
||||||
sock = -1;
|
::close(sock);
|
||||||
|
sock = -1;
|
||||||
|
}
|
||||||
}//Socket::Connection::close
|
}//Socket::Connection::close
|
||||||
|
|
||||||
/// Returns internal socket number.
|
/// Returns internal socket number.
|
||||||
|
@ -214,7 +217,7 @@ signed int Socket::Connection::ready(){
|
||||||
/// The connection status is updated after every read/write attempt, when errors occur
|
/// The connection status is updated after every read/write attempt, when errors occur
|
||||||
/// and when the socket is closed manually.
|
/// and when the socket is closed manually.
|
||||||
/// \returns True if socket is connected, false otherwise.
|
/// \returns True if socket is connected, false otherwise.
|
||||||
bool Socket::Connection::connected(){
|
bool Socket::Connection::connected() const{
|
||||||
return (sock >= 0);
|
return (sock >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +454,24 @@ std::string Socket::Connection::getHost(){
|
||||||
return remotehost;
|
return remotehost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if these sockets are the same socket.
|
||||||
|
/// Does not check the internal stats - only the socket itself.
|
||||||
|
bool Socket::Connection::operator== (const Connection &B) const{
|
||||||
|
return sock == B.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if these sockets are not the same socket.
|
||||||
|
/// Does not check the internal stats - only the socket itself.
|
||||||
|
bool Socket::Connection::operator!= (const Connection &B) const{
|
||||||
|
return sock != B.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the socket is valid.
|
||||||
|
/// Aliases for Socket::Connection::connected()
|
||||||
|
Socket::Connection::operator bool() const{
|
||||||
|
return connected();
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new base Server. The socket is never connected, and a placeholder for later connections.
|
/// Create a new base Server. The socket is never connected, and a placeholder for later connections.
|
||||||
Socket::Server::Server(){
|
Socket::Server::Server(){
|
||||||
sock = -1;
|
sock = -1;
|
||||||
|
@ -661,13 +682,16 @@ Socket::Connection Socket::Server::accept(bool nonblock){
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close connection. The internal socket is closed and then set to -1.
|
/// Close connection. The internal socket is closed and then set to -1.
|
||||||
|
/// If the connection is already closed, nothing happens.
|
||||||
void Socket::Server::close(){
|
void Socket::Server::close(){
|
||||||
#if DEBUG >= 6
|
if (connected()){
|
||||||
fprintf(stderr, "ServerSocket closed.\n");
|
#if DEBUG >= 6
|
||||||
#endif
|
fprintf(stderr, "ServerSocket closed.\n");
|
||||||
shutdown(sock, SHUT_RDWR);
|
#endif
|
||||||
::close(sock);
|
shutdown(sock, SHUT_RDWR);
|
||||||
sock = -1;
|
::close(sock);
|
||||||
|
sock = -1;
|
||||||
|
}
|
||||||
}//Socket::Server::close
|
}//Socket::Server::close
|
||||||
|
|
||||||
/// Returns the connected-state for this socket.
|
/// Returns the connected-state for this socket.
|
||||||
|
@ -675,7 +699,7 @@ void Socket::Server::close(){
|
||||||
/// The connection status is updated after every accept attempt, when errors occur
|
/// The connection status is updated after every accept attempt, when errors occur
|
||||||
/// and when the socket is closed manually.
|
/// and when the socket is closed manually.
|
||||||
/// \returns True if socket is connected, false otherwise.
|
/// \returns True if socket is connected, false otherwise.
|
||||||
bool Socket::Server::connected(){
|
bool Socket::Server::connected() const{
|
||||||
return (sock >= 0);
|
return (sock >= 0);
|
||||||
}//Socket::Server::connected
|
}//Socket::Server::connected
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Socket{
|
||||||
bool canRead(); ///< Calls poll() on the socket, checking if data is available.
|
bool canRead(); ///< Calls poll() on the socket, checking if data is available.
|
||||||
bool canWrite(); ///< Calls poll() on the socket, checking if data can be written.
|
bool canWrite(); ///< Calls poll() on the socket, checking if data can be written.
|
||||||
signed int ready(); ///< Returns the ready-state for this socket.
|
signed int ready(); ///< Returns the ready-state for this socket.
|
||||||
bool connected(); ///< Returns the connected-state for this socket.
|
bool connected() const; ///< Returns the connected-state for this socket.
|
||||||
bool read(const void * buffer, int len); ///< Reads data from socket.
|
bool read(const void * buffer, int len); ///< Reads data from socket.
|
||||||
bool read(const void * buffer, int width, int count); ///< Read call that is compatible with file access syntax.
|
bool read(const void * buffer, int width, int count); ///< Read call that is compatible with file access syntax.
|
||||||
bool write(const void * buffer, int len); ///< Writes data to socket.
|
bool write(const void * buffer, int len); ///< Writes data to socket.
|
||||||
|
@ -62,6 +62,10 @@ namespace Socket{
|
||||||
friend class Server;
|
friend class Server;
|
||||||
bool Error; ///< Set to true if a socket error happened.
|
bool Error; ///< Set to true if a socket error happened.
|
||||||
bool Blocking; ///< Set to true if a socket is currently or wants to be blocking.
|
bool Blocking; ///< Set to true if a socket is currently or wants to be blocking.
|
||||||
|
//overloaded operators
|
||||||
|
bool operator== (const Connection &B) const;
|
||||||
|
bool operator!= (const Connection &B) const;
|
||||||
|
operator bool() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This class is for easily setting up listening socket, either TCP or Unix.
|
/// This class is for easily setting up listening socket, either TCP or Unix.
|
||||||
|
@ -75,7 +79,7 @@ namespace Socket{
|
||||||
Server(int port, std::string hostname = "0.0.0.0", bool nonblock = false); ///< Create a new TCP Server.
|
Server(int port, std::string hostname = "0.0.0.0", bool nonblock = false); ///< Create a new TCP Server.
|
||||||
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
||||||
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
||||||
bool connected(); ///< Returns the connected-state for this socket.
|
bool connected() const; ///< Returns the connected-state for this socket.
|
||||||
void close(); ///< Close connection.
|
void close(); ///< Close connection.
|
||||||
int getSocket(); ///< Returns internal socket number.
|
int getSocket(); ///< Returns internal socket number.
|
||||||
};
|
};
|
||||||
|
|
|
@ -163,8 +163,8 @@ namespace Connector_HTTP{
|
||||||
FLV::Tag tag;///< Temporary tag buffer.
|
FLV::Tag tag;///< Temporary tag buffer.
|
||||||
std::string recBuffer = "";
|
std::string recBuffer = "";
|
||||||
|
|
||||||
std::string Movie = "";
|
std::string Movie;
|
||||||
std::string Quality = "";
|
std::string Quality;
|
||||||
int Segment = -1;
|
int Segment = -1;
|
||||||
int ReqFragment = -1;
|
int ReqFragment = -1;
|
||||||
int temp;
|
int temp;
|
||||||
|
@ -235,32 +235,37 @@ namespace Connector_HTTP{
|
||||||
HTTP_S.SetHeader("Content-Type","text/xml");
|
HTTP_S.SetHeader("Content-Type","text/xml");
|
||||||
HTTP_S.SetHeader("Cache-Control","no-cache");
|
HTTP_S.SetHeader("Cache-Control","no-cache");
|
||||||
std::string manifest = BuildManifest(Movie);
|
std::string manifest = BuildManifest(Movie);
|
||||||
#if DEBUG >= 4
|
|
||||||
printf("Manifest: %s\n", manifest.c_str());
|
|
||||||
#endif
|
|
||||||
HTTP_S.SetBody(manifest);
|
HTTP_S.SetBody(manifest);
|
||||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
printf("Sent manifest\n");
|
printf("Sent manifest\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if DEBUG >= 4
|
|
||||||
printf( "Movie: %s\n", Movie.c_str());
|
|
||||||
#endif
|
|
||||||
streamname = Movie;
|
|
||||||
ready4data = true;
|
ready4data = true;
|
||||||
}//FLASH handler
|
}//FLASH handler
|
||||||
if (handler == HANDLER_PROGRESSIVE){
|
if (handler == HANDLER_PROGRESSIVE){
|
||||||
//we assume the URL is the stream name with a 3 letter extension
|
//we assume the URL is the stream name with a 3 letter extension
|
||||||
std::string extension = HTTP_R.url.substr(HTTP_R.url.size()-4);
|
std::string extension = HTTP_R.url.substr(HTTP_R.url.size()-4);
|
||||||
streamname = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip the extension
|
Movie = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip the extension
|
||||||
/// \todo VoD streams will need support for position reading from the URL parameters
|
/// \todo VoD streams will need support for position reading from the URL parameters
|
||||||
ready4data = true;
|
ready4data = true;
|
||||||
#if DEBUG >= 4
|
|
||||||
printf( "Opening progressive stream: %s\n", streamname.c_str());
|
|
||||||
#endif
|
|
||||||
}//PROGRESSIVE handler
|
}//PROGRESSIVE handler
|
||||||
HTTP_R.Clean(); //clean for any possinble next requests
|
if (Movie != "" && Movie != streamname){
|
||||||
|
#if DEBUG >= 4
|
||||||
|
printf("Buffer switch detected (%s -> %s)! (Re)connecting buffer...\n", streamname.c_str(), Movie.c_str());
|
||||||
|
#endif
|
||||||
|
streamname = Movie;
|
||||||
|
inited = false;
|
||||||
|
ss.close();
|
||||||
|
if (handler == HANDLER_PROGRESSIVE){
|
||||||
|
#if DEBUG >= 4
|
||||||
|
printf("Progressive-mode reconnect impossible - disconnecting.\n");
|
||||||
|
#endif
|
||||||
|
conn.close();
|
||||||
|
ready4data = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HTTP_R.Clean(); //clean for any possible next requests
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
fprintf(stderr, "Could not parse the following:\n%s\n", conn.Received().c_str());
|
fprintf(stderr, "Could not parse the following:\n%s\n", conn.Received().c_str());
|
||||||
|
@ -275,8 +280,12 @@ namespace Connector_HTTP{
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Could not connect to server!\n");
|
fprintf(stderr, "Could not connect to server!\n");
|
||||||
#endif
|
#endif
|
||||||
conn.close();
|
ss.close();
|
||||||
break;
|
HTTP_S.Clean();
|
||||||
|
HTTP_S.SetBody("No such stream is available on the system. Please try again.\n");
|
||||||
|
conn.Send(HTTP_S.BuildResponse("404", "Not found"));
|
||||||
|
ready4data = false;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
fprintf(stderr, "Everything connected, starting to send video data...\n");
|
fprintf(stderr, "Everything connected, starting to send video data...\n");
|
||||||
|
@ -313,7 +322,7 @@ namespace Connector_HTTP{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.close();
|
conn.close();
|
||||||
if (inited) ss.close();
|
ss.close();
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
if (FLV::Parse_Error){fprintf(stderr, "FLV Parser Error: %s\n", FLV::Error_Str.c_str());}
|
if (FLV::Parse_Error){fprintf(stderr, "FLV Parser Error: %s\n", FLV::Error_Str.c_str());}
|
||||||
fprintf(stderr, "User %i disconnected.\n", conn.getSocket());
|
fprintf(stderr, "User %i disconnected.\n", conn.getSocket());
|
||||||
|
|
Loading…
Add table
Reference in a new issue