基于Websocket信息推送的研究与实现

时间:2022-10-11 02:16:51

基于Websocket信息推送的研究与实现

摘要:传统的B/S应用由于HTTP协议的限制,无法实现服务器向浏览器推送信息。虽然可以通过一些技术手段变相实现信息的推送,但明显存在着各种不足。随着Websocket协议被W3C作为标准引入HTML5,各种浏览器开始支持Websocket。通过Websocket,浏览器和服务器之间可以建立一个双向的通信通道,从而实现实时的信息推送功能。在对Websocket进行了初步研究的基础上,通过对一个现实系统的升级,实现了基于Websocket的实时信息推送,达到预期效果。

关键词:B/S;信息推送;Websocket

引言

随着Web 2.0时代的到来,B/S(Browser/Server)构架的应用越来越广泛。在B/S构架的应用中,浏览器与服务器之间的通信采用HTTP(HyperText Transfer Protocol,超文本传输协议)协议。而HTTP协议中,所有的通信都必须由浏览器发起,服务器进行响应,这就是“请求-回复(Request-Response)”模式。因此,在B/S构架的应用中,服务器无法自主的向浏览器发送信息。但随着B/S应用越来越复杂,功能越来越多,客户所期望的用户体验越来越好,越来越多的B/S应用希望服务器能自主的向浏览器发送信息,甚至期望达到浏览器与服务器之间实时的双向通信。这就需要B/S构架中能够实现信息的推送(Web Push)。

1 传统的信息推送方式

传统的B/S构架中,由于HTTP协议的限制,服务器不能主动发起通信,因此要实现类似于服务器推送信息的效果只能采用一些变通的方法。传统的信息推送一般采取如下几种方式实现:定期轮询(Periodic Polling)、长轮询(Long Polling)和流(Streaming)。

1.1 定期轮询

由浏览器每隔一段时间主动向服务器发送一次请求,然后根据服务器的返回数据来获得获得服务器希望推送给浏览器的信息。这种方式下,轮询的时间间隔比较难控制,时间间隔太长,浏览器不能及时的获得服务器需要推送的信息,信息交流不及时,用户体验变差;而如果时间间隔太短,则浏览器将频繁的与服务器进行数据通信,导致服务器负载增大。特别是当服务器无需推送信息的时候,浏览器仍旧会定期的与服务器进行通信,从而浪费大量的网络带宽和资源。

1.2 长轮询

当浏览器向服务器发送请求后,如果服务器有信息需要推送,则立刻回应这个请求,否则,先保持这个连接一段时间,直到服务器有数据需要推送或者连接时间过期为止;浏览器在收到服务器的回应后,将立刻向服务器再次发出新的请求,并等待服务器的回应。这种方式可以减少浏览器与服务器之间的无效通信,从而提高效率,减少系统负担。但当服务器更新频繁时,也就和定期轮询之间没有本质的差别了。

1.3 流

浏览器通过一个隐藏的窗口(比如iframe)向服务器发出一个长连接的请求,服务器接收到这个请求后,做出回应并不断更新连接状态,从而保证服务器与浏览器之间的连接不过期,进而实现服务器将信息推送给浏览器的功能。这种方式在并发数较大的情况下,服务器将会消耗大量的系统资源。

1.4 传统推送方式的不足

虽然上述几种方法均能在传统的B/S构架中实现,但这这些方法很明显的存在着一些弊端:1、定期轮询可能会导致较高的延时,服务器信息不能实时的被推送到浏览器;2、长轮询或流需要使用到一些特定的编程模型或方案,如Comet;3、会带来许多扩展性问题;4、较高的带宽成本和系统资源开销;5、对跨域环境的支持比较有限。

2 基于Websocket协议的信息推送方式

Websocket协议是HTML5提供的一种浏览器与服务器之间进行双向通信的技术。通信双方在完成一次简单的握手操作之后,就建立起一条快速通道,然后利用这个通道可以进行双向通信,自然也就可以实现信息的推送。

2.1 Websocket协议简介

Websocket协议是独立的基于TCP的协议,与HTTP协议之间唯一的联系仅是在浏览器与服务器的握手阶段。

2.1.1 浏览器发出握手请求

首先浏览器以标准的HTTP Get方式向服务器发出握手请求,在请求的头信息中加入了Websocket协议所需要的一些信息。示例如下:

GET /WSHandler.ashx HTTP/1.1

Connection:Upgrade

Host:localhost:1550

Origin:http://localhost:1550

Sec-WebSocket-Key:A3IIMlEc9ARZWlO9ShrePw==

Sec-WebSocket-Version:13

Upgrade:websocket

2.1.2 服务器响应握手请求

服务器在获得这些头信息后,经过处理,以HTTP方式进行回复,回复时也在头信息的部分加入了Websocket协议所需要的信息。示例如下:

HTTP/1.1 101 Switching Protocols

Upgrade: Websocket

Sec-WebSocket-Accept: lJYdhpEDwO4BMgu0meIY94nJIYs=

Connection: Upgrade

经过这样的一个握手过程之后,浏览器与服务器之间就建立起了一条TCP通道。

2.1.3 数据帧

在Websocket协议中,数据使用一系列的帧来传输。基本帧协议定义了带有操作码(opcode)的帧类型、负载长度、和用于“扩展数据”与“应用数据”及它们一起定义的“负载数据”的指定位置。由于采用了帧,Websocket协议不需要像HTTP协议那样发送大量的头信息,从而大大降低了对网络带宽的要求。

2.1.4 Websocket URIs

Websocket协议定义了两种URI,分别是普通的ws-URI和安全的wss-URI。这两种URI均遵循ABNF语法格式,和普通的HTTP协议的URI非常相似。其格式如下:

ws-URI:ws://host[:port]/path[?query]

wss-URI:wss://host[:port]/path[?query]

其中ws-URI的默认端口为80,wss-URI的默认端口为443。

2.2 Websocket协议的优势

相对与传统的信息推送方式,Websocket协议有着诸多的优点:1、支持SSL,安全性高;2、整体性能高,无论是服务器的负载还是网络带宽的成本都大大降低;3、默认采用80或443端口进行数据传输,一般不会被封堵;4、可以支持跨域连接;5、在W3C中定义了Javascript API,客户端编程更加方便。

2.3 Websocket协议存在的问题

当然,Websocket协议也存在一些问题:1、Websocket协议的标准化进程尚未完成,API可能会发生变化,开发应用尚存在一些风险;2、目前仅部分浏览器支持Websocket协议,如IE10之前的IE浏览器均不支持;3、也不是所有的服务器软件都支持Websocket,比如.NET 4.5开始支持Websocket协议,但必须运行在Windows 8或Windows Server 2012平台上才行。

2.4 Websocket在应用中的解决方案

结合Websocket协议的优缺点,我们可以在设计B/S构架的应用时,将实时部分功能和非实时部分功能进行分离,实时性要求强的功能使用Websocket协议实现,而其他功能仍旧使用传统的HTTP协议实现。这样的两种方式能在互不干扰的情况下,发挥出各自的优势,合理利用资源。同时也更便于升级现有的B/S系统,降低成本,提高效率,优化用户体验。

3 Websocket协议在B/S应用中的具体实现

在某订单处理流程中,用户希望浏览器能实时反映出订单状态的变化。原有系统此部分的功能采用基于iframe的流方式实现,虽然基本达到了实时反应订单状态变化的需求,但系统开销很大。因此尝试使用Websocket协议来进行优化。

3.1 服务器的实现

服务器运行平台为Windows Server 2012,安装有.NET 4.5和Microsoft Websockets。在中通过增加一个自定义的HTTP Handler就可以接受浏览器发出的Websocket连接请求并实现与浏览器进行通信。

public class WSHandler : IhttpHandler, IReadOnlySessionState {

public void ProcessRequest(HttpContext context) {

if (context.IsWebSocketRequest) {

context.AcceptWebSocketRequest(new WSOrderHandler());

}

}

}

public class WSOrderHandler : WebSocketHandler {

private static WebSocketCollection m_sessions = new WebSocketCollection();

private string m_username;

public WSOrderHandler() { m_username = ...; }

public override void OnOpen() { m_sessions.Add(this); }

public override void OnMessage(string message) { ... }

public override void OnClose() { m_sessions.Remove(this); }

}

服务器如果需要向所有浏览器发送广播消息,可以通过WSOrderHandler对象中的静态成员m_sessions的Broadcast()方法来实现;服务器如果只需向指定浏览器发送消息,则需先在m_sessions中找到符合要求的session,然后调用Send()方法。

3.2 浏览器的实现

浏览器直接使用W3C所规定的Websocket Javascript API进行开发。首先创建一个Websocket连接。

var wbConnect = new WebSocket('ws://.../WSHandler.ashx');

然后定义onopen、onclose、onmessage、onerror等事件处理函数。

wbConnect.onopen = function (evt) { ... };

wbConnect.onclose = function (evt) { ... };

wbConnect.onmessage = function (evt) { ... };

wbConnect.onerror = function (evt) { ... };

最后,如果浏览器需要发送消息给服务器,则可以通过调用wbConnect.Send()方法实现。

3.3 最终效果

基于以上过程,整个改动涉及的代码量并不多,完全不影响原有系统的其他功能。且在实际运行后,在用户体验不变的情况下,服务器的资源消耗情况大幅改善,取得预期的效果。

4 结束语

Websocket协议虽然尚处在不断完善的阶段,但其在实时应用中的巨大优势已经展露无遗。即使是普通的B/S应用,也能通过使用Websocket协议达到降低系统负载、减少网络成本、优化用户体验的作用。相信随着Websocket协议的进一步完善,将会有越来越多的浏览器和服务器支持Websocket协议,也将会有更多的B/S应用采用Websocket协议。

参考文献

[1] IETF. The WebSocket Protocol[S/OL]. http:///html/rfc6455.

[2] Paul Batum,Stefan Schackow. Building real-time web apps with WebSockets using IIS, and WCF[R/OL]. http:///events/BUILD/BUILD2011/SAC-807T.

[3] 秦久明. Web服务推送技术的研究与实现[J]. 福建电脑,2012,12:65-66+53.

[4] 韩安. HTML5 WebSocket技术研究[J]. 电子世界,2013,20:5-6.

[5] 温照松,易仁伟,姚寒冰. 基于WebSocket的实时Web应用解决方案[J]. 电脑知识与技术,2012,16:3826-3828.

上一篇:GPS在煤矿测量中的应用 下一篇:谈新时期财务分析法综合应用对策