【问题标题】:QTcpSocket does not flush HTTP headers (Comet pattern)QTcpSocket 不刷新 HTTP 标头(彗星模式)
【发布时间】:2016-07-23 00:03:58
【问题描述】:

在 Qt 中实现一个简单的 HTTP 服务器,目的是将实时数据流式传输到 XMLHttpRequest 对象(AJAX/JavaScript)。

问题是设计模式需要通过套接字连接传输部分数据,将XHR中的readyState从'1'(Request)更改为'2'(Headers received),然后更改为'3'(Data收到) - 保持请求未决。这也称为“长轮询”或“彗星”,在大多数浏览器中都应该可以实现。

但是,它一直处于请求状态,直到连接关闭,然后接收到 readyState '2' 和 '4'。这对于 HTTP GET 来说是正常的,但对于这个应用程序来说是不需要的。

JavaScript:

var request = new XMLHttpRequest();
request.onreadystatechange = function() {
    console.log('readyState: ' + this.readyState + ' ' + this.status)
}
request.open("get", "localhost:8080/", true);
request.send();

Qt:

connect(socket, &QTcpSocket::readyRead, [=]()
{
    QByteArray data = m_socket->read(1000);

    socket->write("HTTP/1.1 200 OK\r\n");
    socket->write("Content-Type: text/octet-stream\r\n");
    socket->write("Access-Control-Allow-Origin: *\r\n");
    socket->write("Cache-Control: no-cache, no-store, max-age=0, must-revalidate\r\n");
    socket->flush();
}

所以最大的问题是:如何使 QtTcpSocket 下的网络系统在写入标头(以及随后的数据)后刷新待处理数据,而无需先断开连接? p>

附注:我最初是使用 WebSockets 实现的,但我必须使用的浏览器不支持。


编辑: HTTP 标头格式必须有一组额外的“\r\n”。现在可以了:

connect(socket, &QTcpSocket::readyRead, [=]()
{
    QByteArray data = m_socket->read(1000);

    socket->write("HTTP/1.1 200 OK\r\n");
    socket->write("Content-Type: text/octet-stream\r\n");
    socket->write("Access-Control-Allow-Origin: *\r\n");
    socket->write("Cache-Control: no-cache, no-store, max-age=0, must-revalidate\r\n");
    socket->write("\r\n");
    socket->flush();
}

【问题讨论】:

  • 这更像是一个 HTTP 问题。您确定通过网络发送的数据构成有效的 HTTP 回复吗?您是否将它们与来自符合要求的、正常工作的 HTTP 服务器的回复进行了比较?
  • 这可能是 HTTP 标头问题,但我消除了它,因为它在 flush() 之后执行 disconnectFromHost() 时有效,因此应该验证 HTTP 格式 - 至少在标准 GET 请求方面/回复。
  • 您的readyRead 实现假定它将一次获得1000 个字节。这个假设是错误的,希望你真正的readyRead-attached 仿函数从任意大小的块中组装传入的数据;参见例如this answer 和另一个链接在其中。

标签: javascript qt http comet qtcpsocket


【解决方案1】:

在尝试了一整天不同的 HTTP 标头配置后,现在可以正常工作了。似乎用户“peppe”正在做某事,而我唯一需要的是在标题后添加“\r\n”! (见编辑)。

【讨论】:

  • 在编写使用给定协议的代码时,它有助于阅读协议的文档,尤其是它是免费的,并且是使用谷歌搜索 http protocol 时的第一个结果:) 来自 RFC7320,强调我的:HTTP/ 1.1 消息由一个起始行后跟一系列八位字节组成,其格式类似于 Internet 消息格式 [RFC5322]:零个或多个标头字段(统称为“标头”或“标头部分”),表示标题部分结束的空行,以及可选的消息正文。
猜你喜欢
  • 2011-01-13
  • 2010-09-21
  • 2011-07-30
  • 2011-12-07
  • 2012-07-03
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多