erlang:如何从套接字接收HTTP / RTSP消息?

时间:2019-04-05 11:50:53

标签: http erlang rtsp otp gen-tcp

我想用Erlang管理HTTP或RTSP会话。

例如,RTSP协议的标准会话如下:

OPTIONS rtsp://192.168.1.55/test/ RTSP/1.0\r\n
CSeq: 1\r\n
User-Agent: VLC media player (LIVE555 Streaming Media v2008.07.24)\r\n
...
PLAY rtsp://192.168.1.55/test/ RTSP/1.0\r\n
CSeq: 5\r\n
Session: 1\r\n
Range: npt=0.000-\r\n
User-Agent: VLC media player (LIVE555 Streaming Media v2008.07.24)\r\n

每条消息的长度都不同。 对于erlang,gen_server:listen使用选项{active, true}(用于获取无限数量的数据)或{active, false}(用于获取固定长度的数据)。

有没有推荐的方法来获取和解析长度可变的消息?

1 个答案:

答案 0 :(得分:4)

对于HTTP,请使用为inet:setopts/2函数记录的HTTP数据包模式之一。例如,要将套接字设置为以二进制形式接收HTTP消息,可以在套接字上设置{packet, http_bin}。看看我的simple web server example,了解如何使用HTTP数据包模式。

对于RTSP,没有内置的数据包解析器,但是由于RTSP标头像HTTP一样是面向行的,因此可以使用{packet, line}模式进行自己的标头解析。在这种模式下,您一次只能收到一个标头,直到您收到一个空行,表明标头的末尾。然后,您可以将套接字更改为{packet, raw}模式以接收任何消息正文。 Content-Length标头(如果存在)指示任何邮件正文的大小。

您提到的{active, true}{active, false}套接字模式控制数据如何到达套接字的控制进程(所有者)。

  • {active, true}模式会在套接字到达所有数据后立即将它们发送到控制进程。在这种模式下,数据作为消息到达所有者的消息队列中。在进程消息队列上接收消息非常好,因为它允许进程在处理套接字数据时也可以处理其他与套接字不相关的Erlang消息,但是{active, true}并不经常使用,因为它不提供TCP背压到发件人,这样快速的发件人就会超出收件人的接收范围。
  • {active, false}模式要求接收者在套接字上调用gen_tcp:recv/2,3以检索数据。这没有{active, true}的背压问题,但是由于Erlang进程必须主动请求套接字数据,而不是像它那样只坐在receive循环中,这会使消息处理变得尴尬。其他active模式。
  • 您没有提到的另外两个active模式是{active, once}{active, N}。在{active, once}模式下,接收进程一次通过其消息队列获取一条消息,套接字在每条消息之后移至被动{active, false}模式。要获取另一条消息,接收者必须在准备下一条消息时再次在套接字上设置{active, once}。此模式非常好,因为消息到达过程消息队列的方式与使用{active, true}模式时相同,但是背压仍然有效。 {active, N}模式与之类似,除了在套接字恢复为被动模式之前收到N消息而不是一条消息。