动用SuperWebSocket 构建实时 Web 应用

Web
应用之音讯交互过程一般是客户端通过浏览器发出一个要,服务器端接收和核查完请求后进展处理并返结果让客户端,然后客户端浏览器将信息呈现出,这种体制于信变化不是特意频繁的下尚能相安无事,但是于那些实时要求较强的应用来说,比如说在线娱乐、在线证券、设备监察、新闻在线播报、RSS
订阅推送等等,当客户端浏览器准备见这些消息的下,这些信以劳动器端可能都不合时宜了。所以保持客户端与服务器端的音并是实时
Web 应用之重点因素,对 Web 开发人员来说呢是一个难题。在 WebSocket
规范出来前,开发人员想实现这些实时的 Web
应用,不得不采取局部降的方案,其中最为常用的即使是轮询 (Polling) 和 Comet
技术,而 Comet
技术其实是轮询技术之改善,又只是划分为零星种实现方式,一栽是长轮询机制,一种植叫做流技术。下面我们简要介绍一下立马几种植技术:

轮询:

立是不过早的同等栽实现实时 Web
应用之方案。客户端以得之日间隔为服务端发出请求,以数呼吁的不二法门来维持客户端以及劳务器端的并。这种同步方案的极致要命题目是,在有些数码更新比较频繁的施用里,页面的数码要惦记获取时的结果需再刷新页面,但如此见面生大量底冗余数据以服务器和客户端传输,另外是因为页面是一块处理的,所以当页面加载了前是不克继承操作的。当客户端以稳定频率为服务器发起呼吁的时节,服务器端的数量也许连不曾创新,这样会带诸多无谓的纱传输,所以这是平等种植好低效的实时方案。

长轮询:

添加轮询是对定时轮询的改良与增进,目地是为着降低无效的网传输。当服务器端没有多少更新的时,连接会维持一段时间周期直到数据或者状态改变或时间过,通过这种体制来减无效的客户端和服务器中的互。当然,如果服务端的多寡变动好频繁之口舌,这种机制同定时轮询比较起来没实质上之属性的提高。

流:

横流技术方案便就是于客户端的页面下一个掩蔽的窗口为服务端发出一个丰富连的伸手。服务器端接到这个请后作出应对并不断更新连接状态为保险客户端以及劳务器端的接连不过期。通过这种机制得以用劳动器端的消息源源不断地推客户端。这种机制以用户体验上产生好几问题,需要对不同的浏览器设计不同之方案来改善用户体验,同时这种体制于出现比较特别的情状下,对劳务器端的资源是一个大的考验。

归结这几种植方案,您见面发现这些时咱们所采用的所谓的实时技术并无是真的的实时技术,它们只是当就此
Ajax 方式来学实时的功能,在历次客户端以及劳务器端交互的时刻还是一律次 HTTP
的请和回复的长河,而各一样浅的 HTTP 请求和应对都含有完整的 HTTP
头信息,这就算多了历次传输的数据量,而且这些方案受到客户端和劳动器端的编程实现还比较复杂,在骨子里的应用中,为了模仿比较实际的实时效果,开发人员往往得结构简单单
HTTP
连接来模拟客户端和服务器之间的双向通讯,一个总是用来处理客户端到劳动器端的数量传,一个接连用来处理服务器端到客户端的数码传,这不可避免地添了编程实现之复杂度,也平添了劳动器端的载荷,制约了以体系的扩展性。

HTML5 WebSocket 设计出来的目的就是是设取代轮询和 Comet
技术,使客户端浏览器具备诸如 C/S 架构下桌面系统的实时报道能力。 浏览器通过
JavaScript 向服务器发建立 WebSocket
连接的伸手,连接起以后,客户端与服务器端就得透过 TCP
连接直接交换数据。因为 WebSocket 连接本质上就是是一个 TCP
连接,所以当数码传的泰和多少传输量的高低方面,和轮询以及 Comet
技术比较,具有特别特别之习性优势。Websocket.org
网站对人情的轮询方式以及 WebSocket
调用方式作了一个详尽的测试与比较,将一个简短的 Web 应用分别就此轮询方式及
WebSocket
方式来兑现,在此引用一下他们的测试结果图(http://www.websocket.org/quantum.html
):

轮询和 WebSocket 实现方式的网络负载对比图

透过就张图可以理解的见到,在流量及负载增大的景下,WebSocket
方案相比传统的 Ajax 轮询方案来大幅度的性质优势。这为是为什么咱们以为
WebSocket 是未来实时 Web 应用之首选方案的由。

WebSocket协商计划用来取代使用HTTP作为传输层的双向通信技术,并于现有的底子设备(代理、过滤器、认证)受益。这些技巧作为效率与可靠性的抵要实现,因为HTTP最初并无是用以双向通信的。WebSocket尝试解决在现有HTTP基础设备的环境下现有HTTP双向通信技术之对象;像这样,它计划来行事给HTTP
80、443端口上,并支持HTTP代理及中级设备,即使就意味增加现有条件之一部分扑朔迷离。

接下来,设计并没有拿WebSocket局限为HTTP,未来的落实可在特定的端口上行使重复简便易行的握手,而不待重发明整个协议。最后点是首要的,因为交互式消息之传模式并无紧符合标准的HTTP传输,会以部分部件上引起大的负载。

SuperWebSocket是基于.NET开源Socket框架SuperSocket付出的,
SuperSocket所支撑之大部功力于SuperWebSocket遇收获了持续。用户可透过SuperWebSocket来很快的构建可靠的,高性能的websocket服务器端应用程序。

跟SuperSocket一样,SuperWebSocket可以控制台和windows服务之款型运行,同时她还支持直接运行于Website之内,这样更简化了用户之布置。

WebSocket 协议本质上是一个基于 TCP 的说道。为了树立一个 WebSocket
连接,客户端浏览器首先使奔服务器发起一个 HTTP 请求,这个请与平常的
HTTP 请求例外,包含了一部分附加头信息,其中附加头信息”Upgrade:
WebSocket”
表明这是一个申请协议升级之 HTTP
请求,服务器端解析这些附加的条信息然后来对信息返回给客户端,客户端与服务器端的
WebSocket
连接就建起了,双方就足以经过之连续通道自由之传递信息,并且这个连续会不断在直到客户端或者服务器端的某某一样方主动的关门连接。

脚我们来详细介绍一下 WebSocket 规范,WebSocket
协议来些许有的:握手及数码传。

客户端起的抓手信息:

GET /chat HTTP/1.1

Host: server.example.com

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

Origin: http://example.com

Sec-WebSocket-Protocol: chat, superchat

Sec-WebSocket-Version: 13

服务器端返回的握手信息:

HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Sec-WebSocket-Protocol: chat

客户端握手的带行遵从(HTTP)Request-Line格式,服务器发之指引行遵从(HTTP)Status-Line格式。在片种状况下,引导实践后随着一组未排序的头域。额外的头域也可能出现,如cookie。头的格式和分析在RFC2616定义。

假设客户端和服务器都发送了他们的拉手,如果握手成功,传输数据部分开始。

于实质上的开支过程中,为了使 WebSocket 接口构建 Web
应用,我们第一得构建一个落实了 WebSocket
规范的服务器,服务器端的兑现不叫平台跟开支语言的限,只待遵循
WebSocket 规范即可,目前已经出现了部分比较成熟的 WebSocket
服务器端实现,比如:

  • Kaazing WebSocket Gateway — 一个 Java 实现的 WebSocket Server
  • mod_pywebsocket — 一个 Python 实现的 WebSocket Server
  • Netty —一个 Java 实现之网络框架之中包了针对 WebSocket 的支撑
  • node.js —一个 Server 端的 JavaScript 框架提供了针对 WebSocket 的支持
  • SuperWebSocket –一个.NET/Mono 实现之WebSocket Server(本文的顶梁柱)

浏览器支持

脚是主流浏览器对 HTML5 WebSocket 的支撑情况:

浏览器

支持情况

Chrome

Supported in version 4+

Firefox

Supported in version 4+

Internet Explorer

Supported in version 10+

Opera

Supported in version 10+

Safari

Supported in version 5+

SuperWebSocket是基于.NET开源Socket框架SuperSocket出之,
SuperSocket所支撑之大多数功能在SuperWebSocket吃得了延续。用户可经SuperWebSocket来很快的构建可靠的,高性能的websocket服务器端应用程序。和SuperSocket一样,SuperWebSocket可以控制台和windows服务之花样运行,同时她还支持直接运行于Website之内,这样再简化了用户之布置。

于SuperWebSocket 下充斥最新的0.6本子的代码
http://superwebsocket.codeplex.com/releases/view/86249。代码中蕴藏了一个简单易行的谈天示例:

web.config中配置文件证明参考 SuperSocket系列文档(2)
SuperSocket的核心配置。

在Global.asax文件里看StartSuperWebSocketByConfig:

void StartSuperWebSocketByConfig()
      {
          var serverConfig =
ConfigurationManager.GetSection(“socketServer”) as
SocketServiceConfig;
          if (!SocketServerManager.Initialize(serverConfig))
              return;

          var socketServer =
SocketServerManager.GetServerByName(“SuperWebSocket”) as
WebSocketServer;
          var secureSocketServer =
SocketServerManager.GetServerByName(“SecureSuperWebSocket”) as
WebSocketServer;

          Application[“WebSocketPort”] = socketServer.Config.Port;
          Application[“SecureWebSocketPort”] =
secureSocketServer.Config.Port;

          socketServer.NewMessageReceived += new
SessionEventHandler<WebSocketSession,
string>(socketServer_NewMessageReceived);
          socketServer.NewSessionConnected += new
SessionEventHandler<WebSocketSession>(socketServer_NewSessionConnected);
          socketServer.SessionClosed += new
SessionEventHandler<WebSocketSession,
CloseReason>(socketServer_SessionClosed);

          secureSocketServer.NewSessionConnected += new
SessionEventHandler<WebSocketSession>(secureSocketServer_NewSessionConnected);
          secureSocketServer.SessionClosed += new
SessionEventHandler<WebSocketSession,
CloseReason>(secureSocketServer_SessionClosed);

          if (!SocketServerManager.Start())
              SocketServerManager.Stop();
      }

出三个事件(CommandHandler, NewSessionConnected,
SessionClosed),在每个会话到达的时,将创设新的处理程序来处理。

客户端的贯彻相对于服务器端的实现的话要简单得几近矣,我们仅仅需要表达想象去设计
HTML 用户界面,然后调用 WebSocket JavaScript 接口来和 WebSocket
服务器端来互就好了。当然别忘了采取一个支持 HTML5 和 WebSocket
的浏览器。

当页面初次加载的时光,首先会检测时的浏览器是否支持 WebSocket
并受有相应的提示信息。页面会初始化一个届聊天服务器的 WebSocekt
连接,初始化成功之后,页面会加载对应之 WebSocket 事件处理函数,客户端
JavaScript 代码如下所示:

<script type=”text/javascript”>
     var noSupportMessage = “Your browser cannot support WebSocket!”;
     var ws;

     function resizeFrame() {
         var h = $(window).height();
         var w = $(window).width();
         //Adapt screen height
         $(‘#messageBoard’).css(“height”, (h – 80 – 50 – 100) +
“px”);
         $(‘#messageBoxCell’).css(“width”, (w – 100) + “px”);
         $(‘#messageBox’).css(“width”, (w – 110) + “px”);
     }

     $(document).keypress(function (e) {
         if (e.ctrlKey && e.which == 13 || e.which == 10) {
             $(“#btnSend”).click();
             document.body.focus();
         } else if (e.shiftKey && e.which == 13 || e.which == 10) {
             $(“#btnSend”).click();
             document.body.focus();
         }
     })

     function scrollToBottom(target) {
         target.animate({ scrollTop: target[0].scrollHeight });
     }

     function connectSocketServer() {
         var messageBoard = $(‘#messageBoard’);

         var support = “MozWebSocket” in window ? ‘MozWebSocket’ :
(“WebSocket” in window ? ‘WebSocket’ : null);

         if (support == null) {
             alert(noSupportMessage);
             messageBoard.append(“* ” + noSupportMessage +
“<br/>”);
             return;
         }

         messageBoard.append(“* Connecting to server ..<br/>”);
         // create a new websocket and connect
         ws = new window[support](‘ws://<%= Request.Url.Host
%>:<%= WebSocketPort %>/sample’);

         // when data is comming from the server, this metod is called
         ws.onmessage = function (evt) {
             messageBoard.append(“# ” + evt.data + “<br />”);
             scrollToBottom(messageBoard);
         };

         // when the connection is established, this method is called
         ws.onopen = function () {
             messageBoard.append(‘* Connection open<br/>’);
         };

         // when the connection is closed, this method is called
         ws.onclose = function () {
             messageBoard.append(‘* Connection closed<br/>’);
         }

         //setup secure websocket
         var wss = new window[support](‘wss://<%= Request.Url.Host
%>:<%= SecureWebSocketPort %>/sample’);

         // when data is comming from the server, this metod is called
         wss.onmessage = function (evt) {
             messageBoard.append(“# ” + evt.data + “<br />”);
             scrollToBottom(messageBoard);
         };

         // when the connection is established, this method is called
         wss.onopen = function () {
             messageBoard.append(‘* Secure Connection
open<br/>’);
         };

         // when the connection is closed, this method is called
         wss.onclose = function () {
             messageBoard.append(‘* Secure Connection
closed<br/>’);
         }
     }

     function sendMessage() {
         if (ws) {
             var messageBox = document.getElementById(‘messageBox’);
             ws.send(messageBox.value);
             messageBox.value = “”;
         } else {
             alert(noSupportMessage);
         }
     }

     jQuery.event.add(window, “resize”, resizeFrame);

     window.onload = function () {
         resizeFrame();
         connectSocketServer();
     }
</script>

正文介绍了 WebSocket 规范和 WebSocket
接口,以及同人情的实时技术对比在性能上之优势,并且演示了如何使用
WebSocket 构建一个实时的 Web 应用,最后我们介绍了时的主流浏览器对
HTML5 的支持情况。微软呢一览无遗表述了前途针对 HTML5
的支撑,而且这些支持我们得在 Windows 8 和 IE10
里看到,我们也当各种活动装备,平板电脑及看了 HTML5 和 WebSocket
的身形。WebSocket 将会化为未来开实时 Web
应用之生力军应该是无须悬念的了,作为 Web 开发人员,关注 HTML5,关注
WebSocket。

参考文章:

WebSockets, WCF & Silverlight
5

NancyFx combined with WebSocket server in one
executable

相关文章