有没有类似于RTSP Ping的东西?

3

我目前正在使用C#编写WinForm应用程序,使用RTSP协议从IP摄像机传输视频。一切都很顺利。该应用程序的要求之一是检查IP摄像机是否在线。

因此,我使用System.Net.NetworkInformation.Ping类创建了一个ping功能来ping IP摄像机。例如,如果相机的RTSP URL如下rtsp://[相机IP]:554/Master0-RTSP/1.0,我只需要提取 [相机IP] 部分,并使用Ping类通过其IP地址查看相机是否在线。

起初,它可以正常工作,直到出现了问题,例如输入的IP可能不是预期的IP相机(例如计算机的IP),如果输入设备的IP在线,则ping函数仍然会工作。

我尝试寻找类似于RTSP ping的东西,但没有找到。希望在此事上得到任何建议或意见。非常感谢您的关注。

4个回答

2
“OPTIONS” 可能可行,但标准指定正确的方式是通过使用 “GET_PARAMETER”。RFC2326 明确地概述了这一点。

http://www.ietf.org/rfc/rfc2326.txt

10.8 GET_PARAMETER

GET_PARAMETER请求检索URI中指定的演示文稿或流的参数值。响应内容由实现自己确定。没有实体主体的GET_PARAMETER可以用于测试客户端或服务器存活性(“ping”)。

虽然服务器可能不支持GET_PARAMETER,但无法确切确定该服务器将如何对不需要sessionID甚至的OPTIONS请求做出反应。因此不能保证它将保持您现有的会话处于活动状态。

从同一RFC关于OPTIONS请求的阅读中可以明显看出这一点。

10.1 OPTIONS

该行为相当于[H9.2]中描述的行为。可以在任何时候发出OPTIONS请求,例如,如果客户端即将尝试非标准请求。它不会影响服务器状态。

例:

 C->S:  OPTIONS * RTSP/1.0
        CSeq: 1
        Require: implicit-play
        Proxy-Require: gzipped-messages

 S->C:  RTSP/1.0 200 OK
        CSeq: 1
        Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE

请注意,这些都是虚构的特性(我们希望不会有人故意忽略真正有用的功能,只是为了在本节中展示一个强有力的例子)。
如果不支持 GET_PARAMETER,则应使用要保持活动状态的会话的 SessionId 发出 PLAY 请求。
即使 OPTIONS 不支持,这也应该有效,因为 PLAY 会尊重会话 ID,如果您已经在播放,就没有负面影响。
对于 C# RtspClient,请参阅我的项目 @ https://net7mma.codeplex.com/ 以及 CodeProject 上的文章 @ http://www.codeproject.com/Articles/507218/Managed-Media-Aggregation-using-Rtsp-and-Rtp

正如您所看到的,选项中不需要SessionId。 这可能有效,但它不是标准! - Jay

0

与其使用 ICMP ping,您可能希望保持一个没有视频/音频 RTP 流的辅助 RTSP 会话,定期检查套接字连接的良好状态,并发送 OPTIONSDESCRIBE 命令,例如每分钟一次,以查看设备是否响应。

有人建议使用 GET_PARAMETER 而不是 options,但这是一种较差的方法。 OPTIONS 是强制性的,而 GET_PARAMETER 不是。两者具有不同的目的。两者在服务器端执行开销很小。显然,OPTIONS 是更好的选择。

某些服务器可能不支持设置流参数,因此不支持 GET_PARAMETER 和 SET_PARAMETER。


这是不正确的。你应该使用 GET_PARAMETER 方法。 - Jay
不,我会使用 OPTIONS,因为这是正确的方式。你很快就会发现有些服务器不支持 GET_PARAMETER - Roman R.
仅仅因为服务器不支持它并不意味着什么...请参见我上面的答案。 - Jay
我只是想澄清一下,您将执行我的客户所做的操作。发送选项以获取支持的方法,在发出PLAY以执行保持活动时,如果支持GET_PARAMETER,则会发出该请求,否则将发出重复的PLAY请求。这是标准操作,并适用于所有符合标准的摄像头。 - Jay
1
谢谢大家提供的娱乐,太棒了。如果实现者不一致,为什么不尝试两种方法呢?如果其中一种成功了,那么你就得到了一个成功的 ping。感谢 PLAY 作为服务器保持活动状态的提示,这是一个很好的想法,我在一段时间之后忘记了阅读规范。 - user3259330
显示剩余6条评论

0

再次错误,您应该使用GET_PARAMETER...尝试阅读您链接到的标准。 - Jay
这主要是因为DESCRIBE请求不需要ID。 - Jay

0
你可以使用RTSPClientSharp,并像这样做:
public static async Task TestRTSPConnection(string rtspAddress, string user, string password)
{
        var serverUri = new Uri(rtspAddress);
        var credentials = new NetworkCredential(user, password);

        var connectionParameters = new ConnectionParameters(serverUri, credentials);
        var cancellationTokenSource = new CancellationTokenSource();

        var connectTask = ConnectAsync(connectionParameters, cancellationTokenSource.Token);

        if (await Task.WhenAny(connectTask, Task.Delay(15000 /*timeout*/)) == connectTask)
        {
            if (!connectTask.Result)
            {
                logger.Warn("Connection refused - check username and password");
            }

            logger.Info("Connection test completed");
        }
        else 
        {
            logger.Warn("Connection timed out - check username and password");
        }
    }

    private static async Task<bool> ConnectAsync(ConnectionParameters connectionParameters, CancellationToken token)
    {
        try
        {
            using (var rtspClient = new RtspClient(connectionParameters))
            {
                rtspClient.FrameReceived +=
                    (sender, frame) => logger.Info($"New frame {frame.Timestamp}: {frame.GetType().Name}");

                while (true)
                {
                    logger.Info("Connecting...");

                    try
                    {
                        await rtspClient.ConnectAsync(token);
                    }
                    catch (OperationCanceledException)
                    {
                        logger.Info("Finishing test before connection could be established. Check credentials");
                        return false;
                    }
                    catch (RtspClientException e)
                    {
                        logger.Error($"{e.Message}: {e.InnerException?.Message}");
                        return false;
                    }

                    logger.Info("Connected - camera is online");
                    return true;
                }
            }
        }
        catch (OperationCanceledException)
        {
            return false;
        }
    }

如果你只关心ping和相机是否在线,那么它对我来说非常有效。当凭据不正确时,超时会发生。如果端口未公开或连接被拒绝,则会直接失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接