http服务器如何处理html5网络套接字?

Gop*_*ath 4 java html5 google-app-engine webserver websocket

我正在阅读很多关于HTML5的内容,我特别喜欢网络套接字,因为它们促进了Web服务器和Web浏览器之间的双向通信.

但我们继续阅读关于chrome,opera,firefox,safari为html5做准备.哪个Web服务器已准备好使用Web套接字功能?我的意思是,Web服务器是否能够在今天启动后续通信?谷歌自己的Appengine怎么样?

如何编写利用Java中此功能的示例Web应用程序?

Dre*_*ars 10

Web服务器和浏览器之间的双向通信并不是什么新鲜事.如果将新答案发布到您正在阅读的问题,Stack Overflow会立即执行此操作.使用现有技术实现套接字行为有几种不同的策略:

  • AJAX短轮询:连接到服务器并询问是否有新消息.如果没有,请立即断开连接并在短暂间隔后再次询问.当您不希望将大量长时间运行的空闲连接打开到服务器时,这很有用,但这意味着您只会收到与轮询间隔一样快的新消息,并且会产生建立每次轮询时都有新的HTTP连接.
  • AJAX长轮询:连接到服务器并保持连接打开,直到有新消息可用.这使您可以快速传递新消息并减少频繁的HTTP连接,但这会导致服务器上长时间运行的空闲进程.
  • iframe长轮询:与上面相同,仅使用隐藏的iframe而不是XHR对象.当您想要进行跨站点长轮询时,可用于绕过同源策略.
  • 插件:Flash的XMLSocket,Java applet等可用于建立更接近浏览器的真正低级持久套接字的东西.

HTML5套接字并没有真正改变可用的基础策略.大多数情况下,他们只是将已经使用的策略正式化,并允许明确地识别持久连接,从而更智能地处理.假设您想要向移动浏览器执行基于Web的推送消息传递.通过正常的长轮询,移动设备需要保持清醒才能保持连接.使用WebSockets,当移动设备想要进入休眠状态时,它可以切换到代理的连接,并且当代理接收到新数据时,它可以唤醒设备并传回消息.

服务器端是敞开的.要实现短轮询应用程序的服务器端,您只需要某种按时间顺序排列的消息队列.当客户端连接时,它们可以将新消息从队列中移除,或者它们可以传递偏移量并读取任何比其偏移量更新的消息.

实施服务器端长轮询是您的选择开始缩小的地方.大多数HTTP服务器都是针对短期请求而设计的:连接,请求资源,然后断开连接.如果300人在10分钟内访问您的站点,并且每个人需要2秒钟来连接和下载HTTP资源,那么您的服务器在任何给定时间将平均打开1个HTTP连接.使用长轮询应用程序,您突然保持300倍的连接数.

如果您正在运行自己的专用服务器,您可能能够处理这个问题,但在共享主机平台上,您可能会遇到资源限制,App Engine也不例外.App Engine旨在处理大量低延迟请求,例如短轮询.您可以在App Engine上实施长轮询,但这是不明智的; 运行时间超过30秒的请求将被终止,长时间运行的进程将占用您的CPU配额.

App Engine的解决方案是即将推出的Channel API.渠道API使用Google现有的强大XMPP基础架构实现长轮询.

Brett Bavar和Moishe Lettvin的Google I/O谈话列出了如下使用模式:

App Engine应用程序在远程服务器上创建一个频道,并返回一个频道ID,并将其传递给Web浏览器.

class MainPage(webapp.RequestHandler):

    def get(self):
        id = channel.create_channel(key)
        self.response.out.write(
            {'channel_id': id})
Run Code Online (Sandbox Code Playgroud)

Web浏览器将通道ID传递到同一远程服务器,以通过iframe长轮询建立连接:

<script src='/_ah/channel/jsapi'></script>
<script>
  var channelID = '{{ channel_id }}';
  var channel =
    new goog.appengine.Channel(channelId);
  var socket = channel.open();
  socket.onmessage = function(evt) {
    alert(evt.data);
  }
</script>
Run Code Online (Sandbox Code Playgroud)

当有趣的事情发生时,App Engine应用程序可以将消息推送到用户的频道,浏览器的长轮询请求将立即收到它:

class OtherPage(webapp.RequestHandler):

    def get(self):
        # something happened
        channel.send_message(key, 'bar')
Run Code Online (Sandbox Code Playgroud)