server: separate create and accept

Create separate create and accept methods so that subclasses can create custom
client object.
Configure the server in the client object and prepare for keeping track of
connected clients.
This commit is contained in:
Wim Taymans 2011-01-12 10:57:08 +01:00
parent 8ccebd90b4
commit 6d6ba1ee61
2 changed files with 75 additions and 29 deletions

View file

@ -55,8 +55,9 @@ static void gst_rtsp_server_set_property (GObject * object, guint propid,
const GValue * value, GParamSpec * pspec);
static void gst_rtsp_server_finalize (GObject * object);
static GstRTSPClient *default_accept_client (GstRTSPServer * server,
GIOChannel * channel);
static GstRTSPClient *default_create_client (GstRTSPServer * server);
static gboolean default_accept_client (GstRTSPServer * server,
GstRTSPClient * client, GIOChannel * channel);
static void
gst_rtsp_server_class_init (GstRTSPServerClass * klass)
@ -127,6 +128,7 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass)
GST_TYPE_RTSP_MEDIA_MAPPING,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
klass->create_client = default_create_client;
klass->accept_client = default_accept_client;
GST_DEBUG_CATEGORY_INIT (rtsp_server_debug, "rtspserver", 0, "GstRTSPServer");
@ -135,6 +137,7 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass)
static void
gst_rtsp_server_init (GstRTSPServer * server)
{
server->lock = g_mutex_new ();
server->address = g_strdup (DEFAULT_ADDRESS);
server->service = g_strdup (DEFAULT_SERVICE);
server->backlog = DEFAULT_BACKLOG;
@ -147,6 +150,7 @@ gst_rtsp_server_finalize (GObject * object)
{
GstRTSPServer *server = GST_RTSP_SERVER (object);
g_mutex_free (server->lock);
g_free (server->address);
g_free (server->service);
@ -616,10 +620,20 @@ close_error:
}
}
/* default method for creating a new client object in the server to accept and
* handle a client connection on this server */
/* add the client to the active list of clients, takes ownership of
* the client */
static void
manage_client (GstRTSPServer * server, GstRTSPClient * client)
{
gst_rtsp_client_set_server (client, server);
/* can unref the client now, when the request is finished, it will be
* unreffed async. */
gst_object_unref (client);
}
static GstRTSPClient *
default_accept_client (GstRTSPServer * server, GIOChannel * channel)
default_create_client (GstRTSPServer * server)
{
GstRTSPClient *client;
@ -633,13 +647,22 @@ default_accept_client (GstRTSPServer * server, GIOChannel * channel)
/* set authentication manager */
gst_rtsp_client_set_auth (client, server->auth);
return client;
}
/* default method for creating a new client object in the server to accept and
* handle a client connection on this server */
static gboolean
default_accept_client (GstRTSPServer * server, GstRTSPClient * client,
GIOChannel * channel)
{
/* accept connections for that client, this function returns after accepting
* the connection and will run the remainder of the communication with the
* client asyncronously. */
if (!gst_rtsp_client_accept (client, channel))
goto accept_failed;
return client;
return TRUE;
/* ERRORS */
accept_failed:
@ -647,8 +670,7 @@ accept_failed:
GST_ERROR_OBJECT (server,
"Could not accept client on server socket %d: %s (%d)",
server->server_sock.fd, g_strerror (errno), errno);
gst_object_unref (client);
return NULL;
return FALSE;
}
}
@ -666,21 +688,26 @@ gboolean
gst_rtsp_server_io_func (GIOChannel * channel, GIOCondition condition,
GstRTSPServer * server)
{
gboolean result;
GstRTSPClient *client = NULL;
GstRTSPServerClass *klass;
if (condition & G_IO_IN) {
klass = GST_RTSP_SERVER_GET_CLASS (server);
/* a new client connected, create a client object to handle the client. */
if (klass->accept_client)
client = klass->accept_client (server, channel);
if (klass->create_client)
client = klass->create_client (server);
if (client == NULL)
goto client_failed;
/* can unref the client now, when the request is finished, it will be
* unreffed async. */
gst_object_unref (client);
/* a new client connected, create a client object to handle the client. */
if (klass->accept_client)
result = klass->accept_client (server, client, channel);
if (!result)
goto accept_failed;
/* manage the client connection */
manage_client (server, client);
} else {
GST_WARNING_OBJECT (server, "received unknown event %08x", condition);
}
@ -692,6 +719,12 @@ client_failed:
GST_ERROR_OBJECT (server, "failed to create a client");
return FALSE;
}
accept_failed:
{
GST_ERROR_OBJECT (server, "failed to accept client");
gst_object_unref (client);
return FALSE;
}
}
/**

View file

@ -31,19 +31,22 @@
#include <fcntl.h>
#include <arpa/inet.h>
#ifndef __GST_RTSP_SERVER_H__
#define __GST_RTSP_SERVER_H__
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct _GstRTSPServer GstRTSPServer;
typedef struct _GstRTSPServerClass GstRTSPServerClass;
#include "rtsp-session-pool.h"
#include "rtsp-media-mapping.h"
#include "rtsp-media-factory-uri.h"
#include "rtsp-client.h"
#include "rtsp-auth.h"
#ifndef __GST_RTSP_SERVER_H__
#define __GST_RTSP_SERVER_H__
G_BEGIN_DECLS
#define GST_TYPE_RTSP_SERVER (gst_rtsp_server_get_type ())
#define GST_IS_RTSP_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SERVER))
#define GST_IS_RTSP_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SERVER))
@ -53,16 +56,21 @@ G_BEGIN_DECLS
#define GST_RTSP_SERVER_CAST(obj) ((GstRTSPServer*)(obj))
#define GST_RTSP_SERVER_CLASS_CAST(klass) ((GstRTSPServerClass*)(klass))
typedef struct _GstRTSPServer GstRTSPServer;
typedef struct _GstRTSPServerClass GstRTSPServerClass;
/**
* GstRTSPServer:
*
* This object listens on a port, creates and manages the clients connected to
* it.
*/
struct _GstRTSPServer {
GObject parent;
GObject parent;
GMutex *lock;
/* server information */
gchar *address;
gchar *service;
gint backlog;
gchar *address;
gchar *service;
gint backlog;
struct sockaddr_in server_sin;
@ -79,20 +87,25 @@ struct _GstRTSPServer {
/* authentication manager */
GstRTSPAuth *auth;
/* the clients that are connected */
GList *clients;
};
/**
* GstRTSPServerClass:
*
* @accept_client: Create, configure, accept and return a new GstRTSPClient
* object that handles the new connection on @channel.
* @create_client: Create, configure a new GstRTSPClient
* object that handles the new connection on @channel.
* @accept_client: accept a new GstRTSPClient
*
* The RTSP server class structure
*/
struct _GstRTSPServerClass {
GObjectClass parent_class;
GstRTSPClient * (*accept_client) (GstRTSPServer *server, GIOChannel *channel);
GstRTSPClient * (*create_client) (GstRTSPServer *server);
gboolean (*accept_client) (GstRTSPServer *server, GstRTSPClient *client, GIOChannel *channel);
};
GType gst_rtsp_server_get_type (void);