我想用 Erlang 管理 HTTP 或 RTSP session 。
例如,RTSP 协议(protocol)的标准 session 如下所示:
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}
(用于获取固定长度的数据)。
是否有推荐的方法来获取和解析这种可变长度的消息?
最佳答案
对于 HTTP,使用为 inet:setopts/2
记录的 HTTP 数据包模式之一。功能。例如,要将套接字设置为以二进制形式接收 HTTP 消息,您可以在套接字上设置 {packet, http_bin}
。看看我的simple web server example查看如何使用 HTTP 数据包模式。
对于 RTSP,没有内置的数据包解析器,但是因为 RTSP header 像 HTTP 一样是面向行的,所以您可以使用 {packet, line}
模式进行自己的 header 解析。在那种模式下,您将一次收到一个标题,直到您收到一个表示标题结束的空行。然后您可以将套接字更改为 {packet, raw}
模式以接收任何消息正文。 Content-Length
header (如果存在)表示任何消息正文的大小。
您提到的 {active, true}
与 {active, false}
套接字模式控制数据如何到达套接字的控制进程(所有者)。
{active, true}
模式在数据到达时立即将所有数据从套接字发送到控制进程。在这种模式下,数据作为消息到达所有者的消息队列。在进程消息队列上接收消息很棒,因为它允许进程在处理套接字数据的同时还可以处理其他与套接字无关的 Erlang 消息,但是{active, true}
并不经常使用,因为它不向发送方提供 TCP 背压,因此快速发送方可以超过接收方。{active, false}
模式要求接收方调用gen_tcp:recv/2,3
在套接字上检索数据。这没有{active, true}
的背压问题,但它会使消息处理变得尴尬,因为 Erlang 进程必须主动请求套接字数据,而不是仅仅坐在接收
循环,因为它可以与其他active
模式一起使用。- 您没有提到的另外两种
active
模式是{active, once}
和{active, N}
。在{active, once}
模式下,接收进程一次通过其消息队列获取一条消息,套接字移动到被动{active, false}
模式在每条消息之后。要获取另一条消息,接收方必须在准备好接收下一条消息时再次在套接字上设置{active, once}
。这种模式很好,因为消息到达进程消息队列与使用{active, true}
模式时相同,但背压仍然有效。{active, N}
模式类似,只是在套接字恢复到被动模式之前接收到N
消息,而不是一个。
关于http - erlang:如何从套接字接收 HTTP/RTSP 消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55534748/