我有一个用Twisted编写的简单彗星服务器。 它打印出时间戳。 我还有一个在同一端口上运行的小型静态Web服务器。 服务页面上的javascript尝试通过附加来自彗星服务器的时间戳来更新页面。
但彗星服务器没有显示任何内容。 使用Chromium中的开发人员工具,我可以看到打开了一个长连接。 但是连接超时并且没有任何内容附加到页面上。 为什么不起作用?
这是一个独立的例子:
from twisted.internet import reactor from twisted.internet import task from twisted.web import server from twisted.web.server import Site from twisted.web.resource import Resource import time class ClockPage(Resource): isLeaf = True def __init__(self): self.presence=[] loopingCall = task.LoopingCall(self._print_time) loopingCall.start(1, False) Resource.__init__(self) def render_GET(self, request): # The browser won't display any output until it's gotten a minimum # number of bytes from the server or something. Hence, junk divs. request.write('''<div class="11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"></div><div class="111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111187348937284789374872387847847811111111111111723872187383738271893789217387389737389711111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"></div>''') request.write('<b>%s</b><br>' % (time.ctime(),)) self.presence.append(request) return server.NOT_DONE_YET def _print_time(self): for p in self.presence: p.write('<b>%s</b><br>' % (time.ctime(),)) class UpdatePage(Resource): def render_GET(self, request): return """ <!doctype html> <html> <head> <title>Metastatus</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";></script> <script type="text/javascript"> function addentry(type, msg) { "use strict"; if (type === "new" && msg !== "") { $("#entries").prepend( "<li>" + msg + "</li>" ); } } function waitForMsg() { "use strict"; $.ajax({ type: "GET", url: "http://localhost:8080/clock", async: true, /* If set to non-async, browser shows page as "Loading.."*/ cache: false, timeout: 50000, /* Timeout in ms */ success: function (data) { /* called when request to barge.php completes */ addentry("new", data); /* Add response to a .msg div (with the "new" class)*/ setTimeout( waitForMsg(), /* Request next message */ 1000 /* ..after 1 seconds */ ); }, error: function (XMLHttpRequest, textStatus, errorThrown) { addentry("error", textStatus + " (" + errorThrown + ")"); setTimeout( waitForMsg(), /* Try again after.. */ "15000" ); /* milliseconds (15seconds) */ } }); } $(document).ready(function () { "use strict"; waitForMsg(); /* Start the inital request */ }); </script> </head> <body> <h1>Example</h1> <ul id="entries"></ul> </body> </html>""" if __name__ == '__main__': root = Resource() root.putChild('', UpdatePage()) root.putChild('clock', ClockPage()) factory = Site(root) reactor.listenTCP(8080, factory) reactor.run()I have a simple comet server in written in Twisted. It prints out time stamps. I also have a small static webserver running on the same port. The javascript on the page served tries to update the page by appending the timestamps from the comet server.
But nothing is displayed from the comet server. Using the developer tools in Chromium, I can see that a long connection is opened. But the connection times out and nothing is appended to the page. Why doesn't it work?
Here's a self-contained example:
from twisted.internet import reactor from twisted.internet import task from twisted.web import server from twisted.web.server import Site from twisted.web.resource import Resource import time class ClockPage(Resource): isLeaf = True def __init__(self): self.presence=[] loopingCall = task.LoopingCall(self._print_time) loopingCall.start(1, False) Resource.__init__(self) def render_GET(self, request): # The browser won't display any output until it's gotten a minimum # number of bytes from the server or something. Hence, junk divs. request.write('''<div class="11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"></div><div class="111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111187348937284789374872387847847811111111111111723872187383738271893789217387389737389711111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"></div>''') request.write('<b>%s</b><br>' % (time.ctime(),)) self.presence.append(request) return server.NOT_DONE_YET def _print_time(self): for p in self.presence: p.write('<b>%s</b><br>' % (time.ctime(),)) class UpdatePage(Resource): def render_GET(self, request): return """ <!doctype html> <html> <head> <title>Metastatus</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";></script> <script type="text/javascript"> function addentry(type, msg) { "use strict"; if (type === "new" && msg !== "") { $("#entries").prepend( "<li>" + msg + "</li>" ); } } function waitForMsg() { "use strict"; $.ajax({ type: "GET", url: "http://localhost:8080/clock", async: true, /* If set to non-async, browser shows page as "Loading.."*/ cache: false, timeout: 50000, /* Timeout in ms */ success: function (data) { /* called when request to barge.php completes */ addentry("new", data); /* Add response to a .msg div (with the "new" class)*/ setTimeout( waitForMsg(), /* Request next message */ 1000 /* ..after 1 seconds */ ); }, error: function (XMLHttpRequest, textStatus, errorThrown) { addentry("error", textStatus + " (" + errorThrown + ")"); setTimeout( waitForMsg(), /* Try again after.. */ "15000" ); /* milliseconds (15seconds) */ } }); } $(document).ready(function () { "use strict"; waitForMsg(); /* Start the inital request */ }); </script> </head> <body> <h1>Example</h1> <ul id="entries"></ul> </body> </html>""" if __name__ == '__main__': root = Resource() root.putChild('', UpdatePage()) root.putChild('clock', ClockPage()) factory = Site(root) reactor.listenTCP(8080, factory) reactor.run()最满意答案
在响应完全传递给客户端之前,您不能依赖于在JavaScript中获取响应数据。 这种行为因浏览器而异,因此您有时会看到它的工作方式,而其他时候都无法工作。
您也无法依赖无限期保持打开的连接,主要是由于浏览器和服务器之间的HTTP代理。
You can't rely on getting response data in JavaScript until the response is fully delivered to the client. This behavior varies from browser to browser, so you will see it work as you want sometimes, and not work at all other times.
You also can't rely on connections remaining open indefinitely, largely due to HTTP proxies between the browser and your server.
更多推荐
发布评论