html5 websocketnetty 服务端发送消息怎么向浏览器发送消息

实例70 使用 Kaazing 的远程 Web Socket服务器为浏览器返回简单的回声消息
本文所属图书&>&
《HTML5敏捷实践》共分10章,包括了HTML5中的语义化、新的样式、多媒体支持、新的图形实现方式、更易用交互功能、浏览器客户端存储、地理定位、Web Worker API、Node js 服务器端开发等方面。贯穿全书,作者都&&
回声(Echo)服务器是一个基于Web 的Socket 服务器,是由Kaazing创建的,托管在websocket.org 之上。它通过向发送回声消息演示了WebSocket协议的功能。
这个例子是由 websocket.org 提供的 Echo Test 服务器代码的一个扩展。代码被重构,以符合面向对象的风格。你可以从 websocket.org(http://www.websocket.org/elcho.html)获取原来的代码。
现在打开HTML 文件,用 Script 语言创建一个WebSocketDemo 基本类。由于Script 是一种基于原型的语言,而不是基于类的,所以我们需要使用一个常见的伪类模式来维护代码。如下代码中提供了一个基本的结构:
&script language=&javascript& type=&text/javascript&&&
&WebSocketDemo = function(){
&& return {
&&&&& //& 此处用公共方法
&WebSocketDemo.init(&ws://echo.websocket.org/&);
还需要添加一个id=&output& 的div 标签。这是打印消息的地方。
&h2&WebSocket Test&/h2&
&div id=&output&&&/div&&
WebSocketDemo 类有4 个公开方法:init() 、onOpen() 、onClose()和onMessage() ,还有一个公开属性 ws。ws属性会保存新的WebSocket 对象。
让我们看一下init() 方法。
WebSocketDemo.init()的参数只有一个:URL。将它传递给一个新的WebSocket 对象,注意URL 的前缀是ws://。
WebSocket定义ws://为基本Web socket 连接,定义wss:// 为Web socket连接。在本实例中,只使用基本Web socket连接ws://。
&&& WebSocketDemo = function(){
&&&&& return {
&&&&&&& ws:null,
&&&&&&& init:function(url){
&&&&&&&&&& this.ws = new WebSocket(url);
&&& WebSocketDemo.init(&ws://echo.websocket.org/&);
创建onOpen() 方法将send() 方法包围起来,并监听一旦连接建立成功就会被触发的事件:
&&& WebSocketDemo = function(){
&&&&& return {
&&&&&&& ws:null,
&&&&&&& init:function(url){
&&&&&&&&& this.ws = new WebSocket(url);
&&&&&&&&& this.onOpen();
&&&&& onOpen:function(){
&&&&&&& this.ws.onopen = function(evt) {
&&&&&&& console.log('CONNECTED:' + evt.type);&
&&&&&&& WebSocketDemo.ws.send('html5 hacks');
&&& WebSocketDemo.init(&ws://echo.websocket.org/&);
在onOpen() 方法内部,包含了console.log 打印事件的类型(如图9-1 所示)。
为了建立WebSocket连接,客户端和服务器端在初始握手的过程中从 HTTP 协议升级为WebSocket协议。有很多握手机制,但是除非你要写服务器端的 socket 实现,中WebSocket
API 的实现抽象了具体的细节。
握手请求的格式如下(只显示基本的头信息):
GET /demo HTTP/1.1
Host:echo.websocket.org
Connection:Upgrade
Upgrade:WebSocket
Origin:null
下面是一个握手请求的返回(只显示基本的头信息):
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade:WebSocket
Connection:Upgrade
Server:Kaazing Gateway
使用Google Chrome开发者工具可以查看客户端和服务器端之间的交互。点击&网络&标签,从左边选择&echo.websocket.org &,就可以看到发送和返回的头信息了(如图9-2 所示)。
可以看到请求头中包含的Connection: Upgrade 。还可以看到Upgrade的类型,接收的host 为echo.websocket.org 。
HTTP1.1 包含一个新的请求头,名为 Upgrade,它提供了一种简单的机制从HTTP/1.1变换为其他或者不兼容的未来协议。客户端发送的请求中包含 Upgrade头,通知服务器端它想变换协议。这个通信取决于服务器端对协议变换的验证,如果支持就会变换。
在返回中,可以看到也返回了Upgrade 头和对应的值WebSocket。这告诉客户端浏览器之前请求的Upgrade是支持的,持久的连接已经建立。
现在,稍微修改代码,添加一些公开的方法,暴露更多的连接事件onClose()和onMessage() ,这样能够更有效地演示socket 的内部通信。
&&& onClose:function(){
&&&&& this.ws.onclose = function(evt) {
&&&&&&& console.log('CLOSED:' + ':' + evt.type);
&&& onMessage:function(msg){
&&&&& this.ws.onmessage = function(evt) {&
&&&&&&& console.log('RESPONSE:' + ':' + evt.data);&
&&&&&&& WebSocketDemo.ws.close();
在init() 函数中执行这些新方法:
&&& init:function(url){
&&&&& this.ws = new WebSocket(url);&
&&&&& this.onOpen();&
&&&&& this.onMessage();&
&&&&& this.onClose();
现在刷新浏览器页面就可以看到控制台日志里显示出新的事件方法。onOpen()方法中的第二个请求将&html5 hacks &消息传递给远程回声服务器,服务器返回同样的消息。onMessage() 打印消息并且调用onClose()方法(如图9-3 所示)。 在Chrome的最新版本Canary 版中,开发者工具中包含了一个新的标签,可以看到浏览器和远程服务器之间传递的内容。要查看这些内容,首先要下载 Canary(/intl/en/chrome/browser/canary.html)。以下是使用步骤:
1.打开我们创建的index.html。
2.打开 Chrome开发者工具,按 Apple+Shift+l 组合键(Mac OS X)或者按Ctrl+Shift+l 组合键(Windows 和 )。
3.点击Network 标签,点击Web Sockets。就像在之前例子做得那样。
4.选择&echo.websocket.org &选项。
5.选择WebSocket框架标签。
显示的信息很完善,不需要安装其他第三方工具。
这是一个计数器,显示消息的顺序。
消息的传递方向。
消息发送和接收的时间。
Op-code 分为三类:持续、非控制、控制。持续和非控制Op-code 表示这些消息和控制帧是用于配置协议的:1 表示文本消息,8 表示连接的关闭。
发送内容的字符串长度。
WebSocket发送的实际数据。
图9-4 显示了Canary 中WebSocket标签显示的网络流量。
为了更清楚,让我们概述一下交互过程:
1.浏览器实例化一个WebSocket 对象,并且使用ws://协议传入一个URL参数。
2.浏览器 发送一个HTTP 请求到远程服务器,请求 WebSocket 连接升级。
3.服务器返回头信息表示Connection:& Upgrade 的类型为Upgrade: WebSocket。
4.这触发了onOpen 事件。
5.在onOpen() 方法中,浏览器调用send() 方法并且传入发送的内容。
6.服务器返回同样的内容,触发onMessage() 事件。
7.onMessage() 事件方法打印将发送的内容打印到浏览器的控制台上,然后调用close()方法。
8.onClose()事件方法被触发并且在控制台打印出&CLOSED& 。
以下是完整的代码。这只是组织完善的 WebSocket 库的开始。仿照它开始写你自己的应用吧!
&&meta charset=&utf-8& /&
&title&WebSocket Test&/title&
&script language=&javascript& type=&text/javascript&&
& WebSocketDemo = function(){
&&& return {
&&&&& ws:null,
&&&&& init:function(url){
&&&&&&& this.ws = new WebSocket(url);&
&&&&&&& this.onOpen();&
&&&&&&& this.onMessage();&
&&&&&&& this.onClose();
&&&&& doSend:function(msg){
&&&&&&& this.ws.send = function(evt) {
&&&&&&&&& console.log(evt.timeStamp)
&&&&&&& };
&&&&& onOpen:function(){
&&&&&&& this.ws.onopen = function(evt) {&
&&&&&&&&& console.log('CONNECTED:' + evt.type);&
&&&&&&&&& WebSocketDemo.ws.send('html5 hacks');
&&&&&&& };
&&&&& onClose:function(){
&&&&&&& this.ws.onclose = function(evt) {
&&&&&&&&& console.log('CLOSED:' + ':' + evt.type);
&&&&&&& };
&&&&& onMessage:function(msg){
&&&&&&& this.ws.onmessage = function(evt) {&
&&&&&&&&& console.log('RESPONSE:' + ':' + evt.data);&
&&&&&&&&& WebSocketDemo.ws.close();
&&&&&&& };
& WebSocketDemo.init(&ws://echo.websocket.org/&);
&&/script&
&&h2&WebSocket Test&/h2&
&&div id=&output&&&/div&
您对本文章有什么意见或着疑问吗?请到您的关注和建议是我们前行的参考和动力&&
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
您的浏览器不支持嵌入式框架,或者当前配置为不显示嵌入式框架。
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'织梦模板建站、织梦仿站,推荐选跟版网(专业织梦模板定制下载站),您可以把织梦模板网:
亲,跟版网是专业的DEDECMS模板下载和定制开发服务商!您可以选择或者
浅析HTML5的WebSocket与服务器推送事件
& &以下内容您可能感兴趣: &
WebSockets
Web Sockets 是用于 Web 应用程序的新一代双向通信技术,运行在单一套接字之上,它通过 JavaScript 接口暴漏在 HTML5 兼容的浏览器中。
一旦取得 Web 服务器上的 Web Socket 连接之后,就可以通过调用 send() 方法从浏览器发送数据到服务器上,通过 onmessage 事件处理程序从服务器接收数据到浏览器中。
下面是创建一个新的 WebSocket 对象的 API。
var&Socket&=&new&WebSocket(url,&[protocal]&);&&
第一个参数 url 用于指定要连接的 URL。第二个属性 - 端口是可选的,如果提供,就会指定一个服务器必须支持连接成功的子协议。
WebSocket 属性下面是 WebSocket 对象的属性。假定我们已经创建了上述的 Socket 对象:
Socket.readyState
只读属性readyState表示连接的状态。有以下取值:
0 表示连接尚未建立。
1 表示连接已建立,可以进行通信。
2 表示连接正在进行关闭握手。
3 表示连接已经关闭或者连接不能打开。
Socket.bufferedAmount
只读属性bufferedAmount表示已经使用 send() 方法排队的 URF-8 文本字节数。
WebSocket 事件下面是 WebSocket 对象相关的事件。假定我们已经创建了上述的 Socket 对象:
事件处理程序
Socket.onopen
建立 socket 连接时触发这个事件。
Socket.onmessage
客户端从服务器接收数据时触发。
Socket.onerror
连接发生错误时触发。
Socket.onclose
连接被关闭时触发。
WebSocket 方法下面是 WebSocket 对象相关的方法。假定我们已经创建了上述的 Socket 对象:
Socket.send()
send(data) 方法使用连接传输数据。
Socket.close()
close() 方法用于终止任何现有连接。
服务器推送事件传统的 Web 应用程序生成发送到 Web 服务器端的事件。比如,点击一个链接会从服务器请求一个新页面。
这种从 Web 浏览器到 Web 服务器的时间类型可以称作客服端事件。
随着 HTML5 的出现,WHATWG Web Applications 1.0 引入了一个从 Web 服务器到 Web 浏览器的事件流,被称作服务器推送事件(SSE)。使用 SSE 可以不停的将 DOM 事件推送到用户的浏览器中。
这个事件流方法会打开一个到服务器的持久连接,新消息可用时发送数据到客户端,从而不再需要持续的轮询。
SSE Web 应用程序要在 Web 应用程序中使用服务器推送事件,我们需要给文档添加一个 &eventsource&元素。
&eventsource& 元素的 src 属性应该指向一个 URL,这个 URL 应该提供一个 HTTP 持久连接用于发送包含事件的数据流。
这个 URL 将会指向一个持续发送事件数据的 PHP,PERL 或者任意 Python 脚本。下面是一个简单的期望获得服务器时间的 Web 应用程序示例。
&!DOCTYPE&HTML&&
&type=&text/javascript&&&
/*&Define&event&handling&logic&here&*/ &&
&id=&sse&&&
&&&&src=&/cgi-bin/ticker.cgi&&&&
&id=&ticker&&&
SSE 服务器端脚本服务器端脚本应该发送 Content-type 头指定类型为 text/event-stream,如下所示:
代码如下:print "Content-Type: text/event-stream\n\n";设置 Content-type 之后,服务器端脚本将发送一个后面紧跟事件名称的 Event: 标签。下面的示例将会发送一个以换行符结束的 Server-Time 作为事件名称。
代码如下:print "Event: server-time\n";最后一步是使用 Data: 标签发送事件数据,紧随其后的是以换行符结束的整数字符串值,如下所示:
代码如下:$time = localtime();print "Data: $time\n";下面是用 perl 编写的完整 ticker.cgi:
代码如下:#!/usr/bin/perlprint "Content-Type: text/event-stream\n\n";while(true){
print "Event: server-time\n";
$time = localtime();
print "Data: $time\n";
处理服务器推送事件让我们修改一下我们的 Web 应用程序来处理服务器推送时间。下面是最终示例:
&!DOCTYPE&HTML&&
&type=&text/javascript&&&
&&&document.getElementsByTagName(&eventsource&)[0]. &&
&&&&&&&&&&&&addEventListener(&server-time&,&eventHandler,&false); &&
&&&function&eventHandler(event) &&
&&&&&&&//&Alert&time&sent&by&the&server &&
&&&&&&&document.querySelector('#ticker').innerHTML&=&event. &&
&id=&sse&&&
&&&&src=&/cgi-bin/ticker.cgi&&&&
&id=&ticker&&name=&ticker&&&
&&&[TIME] &&
在测试服务器推送事件之前,建议你确保你的 Web 浏览器支持这一概念。
跟版网-专业织梦模板下载平台,转载请注明出处:
& &精心为您推荐: &
& &邀您关注: &
扫描左侧二维码即可在手机端访问此页面
扫描左侧二维码即可关注跟版网官方微信公众号,获取金币模板,还可以免费仿站哦!
扫描左侧二维码即可加入跟版网官方群,免费获取金币资源并可以与其他织梦高手共同交流学习
跟版网率先实现织梦的三网合一网站,从即日起()日,跟版网会陆续免费分享一批金币资源给需要的朋友,关注本站认证官方微信公众账号并回复相应的提取码,系统会自动将下载地址发送给您,同时这些金币资源也会分享在官方的QQ群中,欢迎各位朋友踊跃加入。另外本站后期会每周选择大家比较喜欢的网站仿制,并免费分享给大家,还有免费送金币活动哦!
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
- dede源码分享
售价:0金币
- dede源码分享
售价:40金币
- dede源码分享
售价:20金币
- dede源码分享
售价:20金币
- dede源码分享
售价:0金币
& & & 跟版网竭力打造中国最大的织梦源码和织梦模板商城,我们有一批经验丰富的设计师和程序员,发展五年,跟版网拥有丰富的织梦模板,欢迎您的咨询,我们将竭诚为您提供最优质的服务。
& & & 跟版网织梦源码商城坚持“创意+品质+服务”的高端理念,运用创意设计的理念为您塑造高品质的网络品牌形象。凭借五年的探索和实践,跟版网织梦源码商城拥有一支经验丰富、技术精湛、尽职尽责的网络服务团队。精品网站建设,从跟版网织梦源码商城建站开始。
& & & 跟版网织梦源码和模板可分为两种形式获得,一种是官方源码,另外一种是会员共享源码。两种源码都分为免费和收费两种形式。
& & & 跟版网官方收费源码可通过支付费用获得,具体操作流程可查看网址:。会员共享源码可通过共享模板获取金币下载。如觉得麻烦,可以联系客服QQ:进行金币充值,充值后可随意下载。developerWorks 社区
本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例来充分展示 WebSocket 的强大和易用。
, 高级软件工程师,
黄晓安,IBM 高级软件工程师,来自 Decision Management Team,具有多年的 Web 开发经验,熟悉 .Net 平台和 Java 平台上的 Web 开发,最近对 HTML5 比较关注。
, 软件工程师,
何亮,IBM CDL 西安软件工程师,来自 Decision Management Team,具有多年的 Java开发经验,熟悉 Java web 开发,关注开源软件和敏捷方法。
, 软件工程师,
许宁,IBM CDL 西安软件工程师,来自 Decision Management Team,熟悉 Java 平台上 Web 应用程序开发,了解开源软件和敏捷开发。关注软件生命周期模型及理论。
作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、WebSocket 等等。这其中有“Web 的 TCP ”之称的 WebSocket 格外吸引开发人员的注意。WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。Web 开发人员可以非常方便地使用 WebSocket 构建实时 web 应用,开发人员的手中从此又多了一柄神兵利器。本文首先介绍 HTML5 WebSocket 的基本概念以及这个规范试图解决的问题,然后介绍 WebSocket 的基本原理和编程接口。接下来会通过一个简单案例来示范怎样实现一个 WebSocket 应用,并且展示 WebSocket 如何在功能强大和编程简单易用上达到的完美统一。最后介绍了目前主流浏览器对 WebSocket 支持的状况、局限性以及未来的展望。实时 Web 应用的窘境Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题。在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。下面我们简单介绍一下这几种技术:轮询:这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的最大问题是,当客户端以固定频率向服务器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。长轮询:长轮询是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高。流:流技术方案通常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。综合这几种方案,您会发现这些目前我们所使用的所谓的实时技术并不是真正的实时技术,它们只是在用 Ajax 方式来模拟实时的效果,在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量,而且这些方案中客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性。WebSocket 的拯救HTML5 WebSocket 设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。因为 WebSocket 连接本质上就是一个 TCP 连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及 Comet 技术比较,具有很大的性能优势。Websocket.org 网站对传统的轮询方式和 WebSocket 调用方式作了一个详细的测试和比较,将一个简单的 Web 应用分别用轮询方式和 WebSocket 方式来实现,在这里引用一下他们的测试结果图:图 1. 轮询和 WebSocket 实现方式的网络负载对比图通过这张图可以清楚的看出,在流量和负载增大的情况下,WebSocket 方案相比传统的 Ajax 轮询方案有极大的性能优势。这也是为什么我们认为 WebSocket 是未来实时 Web 应用的首选方案的原因。WebSocket 规范WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。下面我们来详细介绍一下 WebSocket 规范,由于这个规范目前还是处于草案阶段,版本的变化比较快,我们选择 draft-hixie-thewebsocketprotocol-76版本来描述 WebSocket 协议。因为这个版本目前在一些主流的浏览器上比如 Chrome,、FireFox、Opera 上都得到比较好的支持,您如果参照的是新一些的版本话,内容可能会略有差别。一个典型的 WebSocket 发起请求和得到响应的例子看起来如下:清单 1. WebSocket 握手协议客户端到服务端:
GET /demo HTTP/1.1
Connection: Upgrade
Sec-WebSocket-Key2:
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
[8-byte security key]
服务端到客户端:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin:
WebSocket-Location: ws:///demo
[16-byte hash response]这些请求和通常的 HTTP 请求很相似,但是其中有些内容是和 WebSocket 协议密切相关的。我们需要简单介绍一下这些请求和应答信息,”Upgrade:WebSocket”表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。从客户端到服务器端请求的信息里包含有”Sec-WebSocket-Key1”、“Sec-WebSocket-Key2”和”[8-byte securitykey]”这样的头信息。这是客户端浏览器需要向服务器端提供的握手信息,服务器端解析这些头信息,并在握手的过程中依据这些信息生成一个 16 位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接。一旦连接建立,客户端和服务器端就可以通过这个通道双向传输数据了。在实际的开发过程中,为了使用 WebSocket 接口构建 Web 应用,我们首先需要构建一个实现了 WebSocket 规范的服务器,服务器端的实现不受平台和开发语言的限制,只需要遵从 WebSocket 规范即可,目前已经出现了一些比较成熟的 WebSocket 服务器端实现,比如:
Kaazing WebSocket Gateway —
一个 Java 实现的 WebSocket Server
mod_pywebsocket — 一个 Python 实现的 WebSocket Server
Netty —一个 Java 实现的网络框架其中包括了对 WebSocket 的支持
node.js —一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持如果以上的 WebSocket 服务端实现还不能满足您的业务需求的话,开发人员完全可以根据 WebSocket 规范自己实现一个服务器。在“WebSocket 实战”这一节,我们将使用 Microsoft .NET 平台上的 C# 语言来打造一个简单的 WebSocket 服务器,继而构建一个简单的实时聊天系统。WebSocket JavaScript 接口上一节介绍了 WebSocket 规范,其中主要介绍了 WebSocket 的握手协议。握手协议通常是我们在构建 WebSocket 服务器端的实现和提供浏览器的 WebSocket 支持时需要考虑的问题,而针对 Web 开发人员的 WebSocket JavaScript 客户端接口是非常简单的,以下是 WebSocket JavaScript 接口的定义:清单 2. WebSocket JavaScript 定义 [Constructor(in DOMString url, in optional DOMString protocol)]
interface WebSocket {
readonly attribute DOMString URL;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyS
readonly attribute unsigned long bufferedA
//networking
attribute F
attribute F
attribute F
boolean send(in DOMString data);
void close();
WebSocket implements EventT其中 URL 属性代表 WebSocket 服务器的网络地址,协议通常是”ws”,send 方法就是发送数据到服务器端,close 方法就是关闭连接。除了这些方法,还有一些很重要的事件:onopen,onmessage,onerror 以及 onclose。我们借用 Nettuts 网站上的一张图来形象的展示一下 WebSocket 接口:图 2. WebSocket JavaScript 接口下面是一段简单的 JavaScript 代码展示了怎样建立 WebSocket 连接和获取数据:清单 3. 建立 WebSocket 连接的实例 JavaScript 代码 var
wsServer = 'ws://localhost:8888/Demo';
websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
function onClose(evt) {
console.log("Disconnected");
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
function onError(evt) {
console.log('Error occured: ' + evt.data);
}浏览器支持
下面是主流浏览器对 HTML5 WebSocket 的支持情况:浏览器支持情况ChromeSupported in version 4+FirefoxSupported in version 4+Internet ExplorerSupported in version 10+OperaSupported in version 10+SafariSupported in version 5+WebSocket 实战这一节里我们用一个案例来演示怎么使用 WebSocket 构建一个实时的 Web 应用。这是一个简单的实时多人聊天系统,包括客户端和服务端的实现。客户端通过浏览器向聊天服务器发起请求,服务器端解析客户端发出的握手请求并产生应答信息返回给客户端,从而在客户端和服务器之间建立连接通道。服务器支持广播功能,每个聊天用户发送的信息会实时的发送给所有的用户,当用户退出聊天室时,服务器端需要清理相应用户的连接信息,避免资源的泄漏。以下我们分别从服务器端和客户端来演示这个 Web 聊天系统的实现,在实现方式上我们采用了 C# 语言来实现 WebSocket 服务器,而客户端是一个运行在浏览器里的 HTML 文件。WebSocket 服务器端实现这个聊天服务器的实现和基于套接字的网络应用程序非常类似,首先是服务器端要启动一个套接字监听来自客户端的连接请求,关键的区别在于 WebSocket 服务器需要解析客户端的 WebSocket 握手信息,并根据 WebSocket 规范的要求产生相应的应答信息。一旦 WebSocket 连接通道建立以后,客户端和服务器端的交互就和普通的套接字网络应用程序是一样的了。所以在下面的关于 WebSocket 服务器端实现的描述中,我们主要阐述 WebSocket 服务器怎样处理 WebSocket 握手信息,至于 WebSocket 监听端口的建立,套接字信息流的读取和写入,都是一些常用的套接字编程的方式,我们就不多做解释了,您可以自行参阅本文的附件源代码文件。在描述 WebSocket 规范时提到,一个典型的 WebSocket Upgrade 信息如下所示:GET /demo HTTP/1.1
Connection: Upgrade
Sec-WebSocket-Key2:
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
[8-byte security key]其中 Sec-WebSocket-Key1,Sec-WebSocket-Key2 和 [8-byte security key] 这几个头信息是 WebSocket 服务器用来生成应答信息的来源,依据 draft-hixie-thewebsocketprotocol-76 草案的定义,WebSocket 服务器基于以下的算法来产生正确的应答信息:
逐个字符读取 Sec-WebSocket-Key1 头信息中的值,将数值型字符连接到一起放到一个临时字符串里,同时统计所有空格的数量;
将在第 1 步里生成的数字字符串转换成一个整型数字,然后除以第 1 步里统计出来的空格数量,将得到的浮点数转换成整数型;
将第 2 步里生成的整型值转换为符合网络传输的网络字节数组;
对 Sec-WebSocket-Key2 头信息同样进行第 1 到第 3 步的操作,得到另外一个网络字节数组;
将 [8-byte security key] 和在第 3,第 4 步里生成的网络字节数组合并成一个 16 字节的数组;
对第 5 步生成的字节数组使用 MD5 算法生成一个哈希值,这个哈希值就作为安全密钥返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接至此,客户端和服务器的 WebSocket 握手就完成了,WebSocket 通道也建立起来了。下面首先介绍一下服务器端实现是如何根据用户传递的握手信息来生成网络字节数组的。.NET 平台提供了很方便的对字符串,数值以及数组操作的函数,所以生成字节数组的方法还是非常简单明了的,代码如下:清单 4. 生成网络字节数组的代码
private byte[]   BuildServerPartialKey(string clientKey)
string partialServerKey = "";
byte[] currentK
int spacesNum = 0;
char[] keyChars = clientKey.ToCharArray();
foreach (char currentChar in keyChars)
if (char.IsDigit(currentChar)) partialServerKey += currentC
if (char.IsWhiteSpace(currentChar)) spacesNum++;
currentKey = BitConverter.GetBytes((int)(Int64.Parse(partialServerKey)
/ spacesNum));
if (BitConverter.IsLittleEndian) Array.Reverse(currentKey);
if (currentKey!= null) Array.Clear(currentKey, 0, currentKey.Length);
return currentK
}得到网络字节数组以后,服务器端生成 16 位安全密钥的方法如下所示:清单 5. 生成 16 位安全密钥的代码 private byte[] BuildCompleteServerKey(byte[] serverKey1, byte[] serverKey2,
byte[] last8Bytes)
byte[] concatenatedKeys = new byte[16];
Array.Copy(serverKey1, 0, concatenatedKeys, 0, 4);
Array.Copy(serverKey2, 0, concatenatedKeys, 4, 4);
Array.Copy(last8Bytes, 0, concatenatedKeys, 8, 8);
System.Security.Cryptography.MD5 MD5Service =
System.Security.Cryptography.MD5.Create();
puteHash(concatenatedKeys);
}整个实现是非常简单明了的,就是将生成的网络字节数组和客户端提交的头信息里的 [8-byte security key] 合并成一个 16 位字节数组并用 MD5 算法加密,然后将生成的安全密钥作为应答信息返回给客户端,双方的 WebSocekt 连接通道就建立起来了。实现了 WebSocket 握手信息的处理逻辑,一个具有基本功能的 WebSocket 服务器就完成了。整个 WebSocket 服务器由两个核心类构成,一个是 WebSocketServer,另外一个是 SocketConnection,出于篇幅的考虑,我们不介绍每个类的属性和方法了,文章的附件会给出详细的源代码,有兴趣的读者可以参考。服务器刚启动时的画面如下:图 3. WebSocket 服务器刚启动的画面客户端可以依据这个信息填写聊天服务器的连接地址,当有客户端连接到聊天服务器上时,服务器会打印出客户端和服务器的握手信息,每个客户的聊天信息也会显示在服务器的界面上,运行中的聊天服务器的界面如下:图 4. 有客户端连接到 WebSocket 服务器的以上我们简单描述了实现一个 WebSocket 服务器的最基本的要素,下一节我们会描述客户端的实现。客户端实现客户端的实现相对于服务器端的实现来说要简单得多了,我们只需要发挥想象去设计 HTML 用户界面,然后呼叫 WebSocket JavaScript 接口来和 WebSocket 服务器端来交互就可以了。当然别忘了使用一个支持 HTML5 和 WebSocket 的浏览器,在笔者写这篇文章的时候使用的浏览器是 Firefox。客户端的页面结构是非常简洁的,初始运行界面如下:图 5. 聊天室客户端初始页面当页面初次加载的时候,首先会检测当前的浏览器是否支持 WebSocket 并给出相应的提示信息。用户按下连接按钮时,页面会初始化一个到聊天服务器的 WebSocekt 连接,初始化成功以后,页面会加载对应的 WebSocket 事件处理函数,客户端 JavaScript 代码如下所示:清单 6. 初始化客户端 WebSocket 对象的代码 function ToggleConnectionClicked() {
if (SocketCreated && (ws.readyState == 0 || ws.readyState == 1)) {
ws.close();
Log("准备连接到聊天服务器 ...");
new WebSocket("ws://" + document.getElementById("Connection").value);
SocketCreated =
} catch (ex) {
Log(ex, "ERROR");
document.getElementById("ToggleConnection").innerHTML = "断开";
ws.onopen = WSonO
ws.onmessage = WSonM
ws.onclose = WSonC
ws.onerror = WSonE
function WSonOpen() {
Log("连接已经建立。", "OK");
$("#SendDataContainer").show("slow");
function WSonMessage(event) {
Log(event.data);
function WSonClose() {
Log("连接关闭。", "ERROR");
document.getElementById("ToggleConnection").innerHTML = "连接";
$("#SendDataContainer").hide("slow");
function WSonError() {
Log("WebSocket错误。", "ERROR");
};当用户按下发送按钮,客户端会调用WebSocket对象向服务器发送信息,并且这个消息会广播给所有的用户,实现代码如下所示:function SendDataClicked()
if (document.getElementById("DataToSend").value != "") {
ws.send(document.getElementById("txtName").value + "说 :\"" +
document.getElementById("DataToSend").value + "\"");
document.getElementById("DataToSend").value = "";
};如果有多个用户登录到聊天服务器,客户端页面的运行效果如下所示:图 6. 聊天客户端运行页面至此我们已经完成了一个完整的 WebSocket 客户端实现,用户可以体验一下这个聊天室的简单和快捷,完全不用考虑页面的刷新和繁琐的 Ajax 调用,享受桌面程序的用户体验。WebSocket 的强大和易用可见一斑,您完全可以在这个基础上加入更多的功能,设计更加漂亮的用户界面,切身体验 WebSocket 的震撼力。完整的客户端代码请参阅附件提供的源代码。WebSocket 的局限性WebSocket 的优点已经列举得很多了,但是作为一个正在演变中的 Web 规范,我们也要看到目前用 Websocket 构建应用程序的一些风险。首先,WebSocket 规范目前还处于草案阶段,也就是它的规范和 API 还是有变动的可能,另外的一个风险就是微软的 IE 作为占市场份额最大的浏览器,和其他的主流浏览器相比,对 HTML5 的支持是比较差的,这是我们在构建企业级的 Web 应用的时候必须要考虑的一个问题。总结本文介绍了 HTML5 WebSocket 的横空出世以及它尝试解决的的问题,然后介绍了 WebSocket 规范和 WebSocket 接口,以及和传统的实时技术相比在性能上的优势,并且演示了怎样使用 WebSocket 构建一个实时的 Web 应用,最后我们介绍了当前的主流浏览器对 HTML5 的支持情况和 WebSocket 的局限性。不过,我们应该看到,尽管 HTML5 WebSocket 目前还有一些局限性,但是已经是大势所趋,微软也明确表达了未来对 HTML5 的支持,而且这些支持我们可以在 Windows 8 和 IE10 里看到,我们也在各种移动设备,平板电脑上看到了 HTML5 和 WebSocket 的身影。WebSocket 将会成为未来开发实时 Web 应用的生力军应该是毫无悬念的了,作为 Web 开发人员,关注 HTML5,关注 WebSocket 也应该提上日程了,否则我们在新一轮的软件革新的浪潮中只能做壁上观了。
下载描述名字大小示例代码94KB
参考资料 :HTML5 的官方网站
:一个专门介绍和推广 WebSocket 技术的网站
:维基百科上关于 WebSocket 的介绍
:nettut 网站上关于 WebSocket 的介绍
:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过
栏目,迅速了解 Web 2.0 的相关概念。查看 ,了解更多和 HTML5 相关的知识和动向。加入 。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
免费下载、试用软件产品,构建应用并提升技能。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Web developmentArticleID=781302ArticleTitle=使用 HTML5 WebSocket 构建实时 Web 应用publish-date=}

我要回帖

更多关于 服务端发送消息给app 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信