简体   繁体   English

Gstreamer RTSP客户端超时问题

[英]Gstreamer RTSP client timeout issues

I am having some problems with the Gstreamer's RTSP client. 我在Gstreamer的RTSP客户端上遇到了一些问题。 So I have a client program and I want it to give proper responses to me from a watch dog function whenever the RTSP client receives/sends a message or returns an error etc. and exit the code accordingly if there is an error. 因此,我有一个客户端程序,我希望它在RTSP客户端接收/发送消息或返回错误等时,从看门狗功能给我适当的响应,如果有错误,则相应地退出代码。 So what I do is this, 所以我要做的是

  1. I simply create an RTSP server using VLC on my machine and I connect to this server. 我只是在计算机上使用VLC创建RTSP服务器,然后连接到该服务器。 I can create the connection successfully apparently. 我显然可以成功创建连接。
  2. I stop the server by simply closing the VLC. 我只需关闭VLC即可停止服务器。 So now the watch dog function should receive proper error code and print it to the screen. 因此,现在看门狗功能应该接收正确的错误代码并将其打印到屏幕上。 But it never does that. 但是它从来没有那样做。 In the RTSP documentation of Gstreamer there is a function called gst_rtsp_connection_connect which takes a connection and a timeout value and in the documentation it is stated that if the timeout is NULL, this function can block forever. 在Gstreamer的RTSP文档中,有一个名为gst_rtsp_connection_connect的函数,该函数gst_rtsp_connection_connect一个连接和一个超时值,并且在文档中指出,如果超时为NULL,则此函数可以永远阻塞。 So I though since I put NULL in the timeout field, it never times out and believes it is still connected to the server and thus never gets inside any of the watch dog functions. 因此,尽管我由于将NULL放入超时字段中,所以它永远不会超时,并认为它仍连接到服务器,因此永远不会进入任何看门狗函数。 However, when I applied, say a 5 second timeout, then it directly kills the connection after 5-7 seconds and gets inside some of the watch dog functions. 但是,当我申请时(例如5秒钟超时),则5-7秒后它将直接终止连接并进入某些看门狗功能。 I don't want my code to give an error immediately even though there is a proper connection and the server is still up working, I just want it to give some errors when the server is actually down and some timeout time has passed. 即使连接正确并且服务器仍在运行,我也不希望我的代码立即给出错误,我只是想在服务器实际上关闭并且经过了一些超时时间后给出一些错误。 How can I fix this? 我怎样才能解决这个问题?

Here is my complete code, includes and libraries are at the top of the code: 这是我完整的代码,包含和库位于代码的顶部:

/*
 * INCLUDES
 * /usr/include/gstreamer-1.0
 * /usr/include/glib-2.0
 * /usr/lib/x86_64-linux-gnu/glib-2.0/include
 * /usr/include/gstreamer-1.0/gst/rtsp
 *
 * LIBRARIES
 * gstreamer-1.0
 * gstrtsp-1.0
 * gobject-2.0
 * glib-2.0
 *
 * MISC.
 * -std=c99
 *
 *
 *
 * */

#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtsptransport.h>
#include <gst/rtsp/gstrtspconnection.h>
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>

static GstRTSPStatusCode
tunnel_start (GstRTSPWatch * watch, gpointer user_data)
{
  g_print("tunnel_start\n");
  return GST_RTSP_STS_OK;
}

static GstRTSPResult
tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
{
    g_print("tunnel_complete\n");
  return GST_RTSP_OK;
}

static GstRTSPResult
tunnel_lost (GstRTSPWatch * watch, gpointer user_data)
{
    g_print("tunnel_lost\n");
  return GST_RTSP_OK;
}

static GstRTSPResult
closed (GstRTSPWatch * watch, gpointer user_data)
{
    g_print("closed\n");
  return GST_RTSP_OK;
}

static GstRTSPResult
message_sent (GstRTSPWatch * watch, guint id, gpointer user_data)
{
    g_print("message_sent\n");
  return GST_RTSP_OK;
}

static GstRTSPResult
message_received (GstRTSPWatch *watch, GstRTSPMessage *message, gpointer user_data) {
    g_print("message_received\n");
  return GST_RTSP_OK;
}

static  GstRTSPResult
error (GstRTSPWatch *watch, GstRTSPResult result, gpointer user_data) {
    g_print("error\n");
  return GST_RTSP_OK;
}

static  GstRTSPResult
error_full (GstRTSPWatch *watch, GstRTSPResult result, GstRTSPMessage *message, guint id, gpointer user_data) {
    g_print("error_full\n");
  return GST_RTSP_OK;
}

static GstRTSPWatchFuncs watch_funcs = {
  message_received,
  message_sent,
  closed,
  error,
  tunnel_start,
  tunnel_complete,
  error_full,
  tunnel_lost
};





/* main method */
int main (int argc, char *argv[]) {
    GMainLoop *loop;
    loop = g_main_loop_new (NULL, FALSE);

    GstRTSPUrl *url = NULL;
    GstRTSPConnection *conn = NULL;
    GstRTSPResult res;
    GstRTSPWatch *watch;
    GTimeVal *timeout;
    timeout->tv_sec = 5;
    timeout->tv_usec = 5000000;

    res = gst_rtsp_url_parse ("rtsp://localhost:5000/test", &url);
    res = gst_rtsp_connection_create (url, &conn);
    if (res == GST_RTSP_OK) {
      g_print("Connection created.\n");
    }


    res = gst_rtsp_connection_connect (conn, timeout);
    if (res == GST_RTSP_OK) {
      g_print("Connection connected.\n");
    } else {
      g_printerr("Connection not connected. Exiting with code 500.\n");
      exit(500);
    }



    watch = gst_rtsp_watch_new (conn, &watch_funcs, loop, NULL);
    if (watch == NULL) {
        g_print("Failed to create watch.\n");
    }


    gst_rtsp_watch_attach (watch, NULL);
    gst_rtsp_url_free (url);

    g_main_loop_run (loop);

    return 0;
}

This code is working as intended. 该代码按预期工作。 I was making wrong type of tests. 我进行了错误的测试类型。

The way I "stopped" the rtsp server was just pressing the "stop" button of VLC. 我“停止” rtsp服务器的方式只是按下VLC的“停止”按钮。 This does not destroy the server, server is still there, just not making any kind of stream and client is still connected to the server without problem because server still exists. 这不会破坏服务器,服务器仍在那儿,只是不进行任何形式的流传输,并且客户端仍然可以毫无问题地连接到服务器,因为服务器仍然存在。 When I close the VLC instead to destroy the server, it gets into the right watch dog function. 当我关闭VLC销毁服务器时,它进入了正确的看门狗功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM