opening titles简谱:Dojo WebSocket 应用 - Dojo中文博客 - CSDN博客

来源:百度文库 编辑:偶看新闻 时间:2024/04/20 07:09:29
Dojo WebSocket 应用 收藏
Dojo 1.6 提供了一个基于WebSocket API开发的用于实时通信的dojo socket API, WebSocket 提供了一种支持全双工通信的对象,我们可以非常方便的实时的将消息从服务端直接发送到客户端。Dojo的新 dojox.socket 模块还提供了WebSocket API所没有的基于HTTP的 long-polling。Dojox.socket 模块设计上十分简单,轻量级并且与协议无关。原来dojo有很多针对特定协议开发的模块,如CometD 和 RestChannels, 但是还有大量的其他协议无法满足,所以 dojox.socket 模块只是简单的通过HTTP 协议或WebSocket连接 传递字符串,这也保证了他对所有系统的兼容性.dojox.socket 最简单的使用方式:view plaincopy to clipboardprint?
var socket = dojox.socket ( "/comet" ) ; 
var socket = dojox.socket ( "/comet" ) ;
 
我们现在便可以监听服务器端的消息事件:view plaincopy to clipboardprint?
socket.on ( "message" , function ( event) {  
  var data = event.data ;  
  // 处理服务器端返回的 data  
} ) ; 
socket.on ( "message" , function ( event) {
  var data = event.data ;
  // 处理服务器端返回的 data
} ) ;
 
socket.on() 用于注册监听函数,捕获后台消息事件,我么也可以用socket.connect() 实现相同的功能。我们也可以用 send() 方法给服务器端发送消息. 但是在此之前我们通常要保证和后台的连接已经建立起来了:view plaincopy to clipboardprint?
socket.on ( "open" , function ( event) {  
  socket.send ( "hi server" ) ;  
} ) ; 
socket.on ( "open" , function ( event) {
  socket.send ( "hi server" ) ;
} ) ;
 
最后,我们也可以监听“close”事件,判断连接的关闭情况,我们可以通过调用socket.close()来开启连接关闭的进程。 dojox.socket 也能接受一些标准的Dojo IO 参数用于初始化和服务器端的连接,比如我们可以加入我们的消息头:view plaincopy to clipboardprint?
var socket = dojox.socket ( {  
        url:"/comet" ,  
        headers: {  
                "Accept" : "application/json" ,  
                "Content-Type" : "application/json" 
        } } ) ; 
var socket = dojox.socket ( {
        url:"/comet" ,
        headers: {
                "Accept" : "application/json" ,
                "Content-Type" : "application/json"
        } } ) ;
 
这样浏览器基于自身的特点会将这些URL路径转换为WebSocket URL (using ws:// scheme) 或者HTTP URL。有的服务器端只支持HTTP/long-polling(长轮询) (不支持真正的WebSocket). 这时候,我们可以显式创建一个基于 long-poll 的连接:view plaincopy to clipboardprint?
var socket = dojox.socket .LongPoll ( {  
        url:"/comet" ,  
        headers: {  
                "Accept" : "application/json" ,  
                "Content-Type" : "application/json" 
        } } ) ; 
var socket = dojox.socket .LongPoll ( {
        url:"/comet" ,
        headers: {
                "Accept" : "application/json" ,
                "Content-Type" : "application/json"
        } } ) ;
 
我们也可以使用dojo.io.script.get 连接到服务器.  dojox.io.xhrPlugins 还支持跨域的 long-polling, 他们都能很好的和 dojox.socket 协同工作。Auto-Reconnect
除了 dojox.socket , 我们还有 dojox.socket.Reconnect 模块. 他封装了 socket, 提供了自动重新连接的功能. 当一个socket连接由于网络或服务器的问题关闭时,他会自动周期性的重新连接服务器,此方式基于回退算法,保证了最少的资源消耗。我们能通过如下代码把一个普通的socket升级到自动重连的socket:socket = dojox.socket .Reconnect ( socket) ;
 
Dojo WebSocket 和Object Stores协同工作
Dojo 1.6 新曾的另一个很强大的功能是 new Dojo object store API (取代 Dojo Data API), 基于 the HTML5 IndexedDB object store API. Dojo 1.6 支持很多对 store 的包装器,  Observable store 提供了事件通知机制,能很好的和Comet driven updates 联合使用. Observable 是一个 store 包装器. 使用方式:先创建一个store,再用Observable包装他:view plaincopy to clipboardprint?
define( "my-module" , function ( require) {  
  var JsonRest = require( "dojo/store/JsonRest" ) ;  
  var Observable = require( "dojo/store/Observable" ) ;  
  var store = new JsonRest( { data:myData} ) ;  
  store = Observable( store) ;  
} ) ; 
define( "my-module" , function ( require) {
  var JsonRest = require( "dojo/store/JsonRest" ) ;
  var Observable = require( "dojo/store/Observable" ) ;
  var store = new JsonRest( { data:myData} ) ;
  store = Observable( store) ;
} ) ;
 
这个store 此时便具有 observe() 方法, 可以通过此方法绑定监听函数,用于针对data变化是做出相应处理,我们此刻便能够通过服务器端的消息得知data的变化,并手动通知store的Observe:view plaincopy to clipboardprint?
socket.on ( "message" , function ( event) {  
  var existingId = event.data .id ;  
  var object = event.data .object ;  
  store.notify ( object, existingId) ;  
} ) ; 
socket.on ( "message" , function ( event) {
  var existingId = event.data .id ;
  var object = event.data .object ;
  store.notify ( object, existingId) ;
} ) ;
 
store.notify()中,不传入id参数则表示 新增object,不传入object参数表示删除,两个都有便是修改。处理 Long-Polling Long-polling(长轮询)请求和普通的polling(轮询)请求不同在于:普通的polling是一次请求,一次查询和回答(服务器返回结果),而Long-polling请求则是一次请求,多次查询,直到有消息,再回答(返回)。Long-polling 方式的连接需要服务端的支持。在很多应用中,服务器需要足够的请求中的cookie信息来决定发送什么信息到客户端。由于有很多的协议的存在,我们可以通过在请求的消息头中放入相关信息来以示区别:view plaincopy to clipboardprint?
var socket = dojox.socket .LongPoll ( {  
        url:"/comet" ,  
        headers: {  
                "Accept" : "application/json" ,  
                "Content-Type" : "application/json" ,  
                "Client-Id" : Math.random ( )  
        } } ) ; 
var socket = dojox.socket .LongPoll ( {
        url:"/comet" ,
        headers: {
                "Accept" : "application/json" ,
                "Content-Type" : "application/json" ,
                "Client-Id" : Math.random ( )
        } } ) ;
 
dojox.socket 包含参数 Pragma: long-poll 来标识一系列 long-poll 请求中的第一个请求,从而帮助服务器处理连接的建立和超时。我们也能用 dojox.socket 支持其他的协议:CometD
初始化 Comet connection 连接 CometD 服务器, 我们可以进行 CometD 握手, 连接和订阅:view plaincopy to clipboardprint?
var socket = dojox.socket ( "/cometd" ) ;  
function send( data) {  
  return socket.send ( dojo.toJson ( data) ) ;  
}  
socket.on ( "connect" , function ( ) {  
  // 发送一次握手  
  send( [  
    {  
       "channel" : "/meta/handshake" ,  
       "version" : "1.0" ,  
       "minimumVersion" : "1.0beta" ,  
       "supportedConnectionTypes" : [ "long-polling" ] // or ["callback-polling"] for x-domain  
     }  
  ] ) .then ( function ( data) {  
    // 等待回复,这样我们可以通过提供的客户端id建立连接  
    data = dojo.fromJson ( data) ;  
    if ( data.error ) {  
      throw new Error( error) ;  
    }  
    // 获取客户端id  
    clientId = data.clientId ;  
    // 发送链接消息  
    send( [  
      {  
         "channel" : "/meta/connect" ,  
         "clientId" : clientId,  
         "connectionType" : "long-polling" 
       } ,  
       {  // 同时发送订阅消息  
         "channel" : "/meta/subscribe" ,  
         "clientId" : clientId,  
         "subscription" : "/foo/**" 
       }  
    ] ) ;  
    socket.on ( "message" , function ( ) {  
      // 处理服务器返回的消息  
    } ) ;  
  } ) ;  
} ) ; 
var socket = dojox.socket ( "/cometd" ) ;
function send( data) {
  return socket.send ( dojo.toJson ( data) ) ;
}
socket.on ( "connect" , function ( ) {
  // 发送一次握手
  send( [
    {
       "channel" : "/meta/handshake" ,
       "version" : "1.0" ,
       "minimumVersion" : "1.0beta" ,
       "supportedConnectionTypes" : [ "long-polling" ] // or ["callback-polling"] for x-domain
     }
  ] ) .then ( function ( data) {
    // 等待回复,这样我们可以通过提供的客户端id建立连接
    data = dojo.fromJson ( data) ;
    if ( data.error ) {
      throw new Error( error) ;
    }
    // 获取客户端id
    clientId = data.clientId ;
    // 发送链接消息
    send( [
      {
         "channel" : "/meta/connect" ,
         "clientId" : clientId,
         "connectionType" : "long-polling"
       } ,
       {  // 同时发送订阅消息
         "channel" : "/meta/subscribe" ,
         "clientId" : clientId,
         "subscription" : "/foo/**"
       }
    ] ) ;
    socket.on ( "message" , function ( ) {
      // 处理服务器返回的消息
    } ) ;
  } ) ;
} ) ;
 
Socket.IO
Socket.IO 提供了一个底层的接口,类似 dojox.socket, 支持简单的文本消息传送,下面是一个连接Socket.IO服务器的例子:view plaincopy to clipboardprint?
var args, ws = typeof WebSocket != "undefined" ;  
var socket = dojox.socket ( args = {  
  url: ws ? "/socket.io/websocket" : "/socket.io/xhr-polling" ,  
  headers:{  
    "Content-Type" :"application/x-www-urlencoded" 
  } ,  
  transport: function ( args, message) {  
    args.content = message; // 利用 URL-编码发送消息,避免直接发送原始消息本身  
    dojo.xhrPost ( args) ;  
  } ;  
} ) ;  
var sessionId;  
socket.on ( "message" , function ( ) {  
  if ( !sessionId) {  
    sessionId = message;  
    args.url += ‘/’ + sessionId;  
  } else if ( message.substr ( 0 , 3 ) == ‘~h~’ ) {  
  }  
} ) ; 
var args, ws = typeof WebSocket != "undefined" ;
var socket = dojox.socket ( args = {
  url: ws ? "/socket.io/websocket" : "/socket.io/xhr-polling" ,
  headers:{
    "Content-Type" :"application/x-www-urlencoded"
  } ,
  transport: function ( args, message) {
    args.content = message; // 利用 URL-编码发送消息,避免直接发送原始消息本身
    dojo.xhrPost ( args) ;
  } ;
} ) ;
var sessionId;
socket.on ( "message" , function ( ) {
  if ( !sessionId) {
    sessionId = message;
    args.url += ‘/’ + sessionId;
  } else if ( message.substr ( 0 , 3 ) == ‘~h~’ ) {
  }
} ) ;
 
Comet Session Protocol
以下是连接 Comet Session Protocol 服务器的例子:view plaincopy to clipboardprint?
var args, socket = dojox.socket ( args = {  
  url: "/csp/handshake" 
} ) ;  
function send( data) {  
  return socket.send ( dojo.toJson ( data) ) ;  
}  
var sessionId = Math.random ( ) .toString ( ) .substring ( 2 ) ;  
socket.on ( "connect" , function ( ) {  
  send( { session:sessionId} ) .then ( function ( ) {  
    args.url = "/csp/comet" ;  
    send( { session:sessionId} ) ;  
  } ) ;  
} ) ; 
var args, socket = dojox.socket ( args = {
  url: "/csp/handshake"
} ) ;
function send( data) {
  return socket.send ( dojo.toJson ( data) ) ;
}
var sessionId = Math.random ( ) .toString ( ) .substring ( 2 ) ;
socket.on ( "connect" , function ( ) {
  send( { session:sessionId} ) .then ( function ( ) {
    args.url = "/csp/comet" ;
    send( { session:sessionId} ) ;
  } ) ;
} ) ;
 
Tunguska
Tunguska 提供了一个基于 Comet 订阅数据变化的接口,以下是一个与Tunguska 服务器通信的简单示例:view plaincopy to clipboardprint?
var socket = dojox.socket ( {  
        url:"/comet" ,  
        headers: {  
                "Accept" : "application/json" ,  
                "Content-Type" : "application/json" ,  
                "Client-Id" : Math.random ( )  
        } } ) ;    
function send( data) {  
  return socket.send ( dojo.toJson ( data) ) ;  
}  
socket.on ( "connect" , function ( ) {  
  // 订阅了MyTable 的所有改动  
  send( [ { "to" :"/MyTable/*" , "method" :"subscribe" } ] ) ;  
} ) ; 
var socket = dojox.socket ( {
        url:"/comet" ,
        headers: {
                "Accept" : "application/json" ,
                "Content-Type" : "application/json" ,
                "Client-Id" : Math.random ( )
        } } ) ; 
function send( data) {
  return socket.send ( dojo.toJson ( data) ) ;
}
socket.on ( "connect" , function ( ) {
  // 订阅了MyTable 的所有改动
  send( [ { "to" :"/MyTable/*" , "method" :"subscribe" } ] ) ;
} ) ;
 
Conclusion
Dojo的socketAPI是一个和各种不同服务器建立实时连接并通信的模块,这是Dojo1.6令人振奋的一个改进。发表于 @ 2010年11月25日 16:39:00 | 评论( 6 ) | 编辑| 举报| 收藏 旧一篇:JavaScript 开发测试工具概览 | 新一篇:Dojo:不容忽视的RIA框架
查看最新精华文章 请访问博客首页相关文章DJBOY850317 发表于2010年11月30日 16:17:45  IP:119.191.73.*举报回复删除
o0o0oo0o0 发表于2010年11月30日 17:18:48  IP:123.6.1.*举报回复删除
有没有1.6 的下载地址啊 dojotoolkit 发表于2010年12月1日 15:04:56  IP:220.248.0.*举报回复删除
回复 o0o0oo0o0:1.6还没有发布。。需要最新代码可以去nightlybuild:http://archive.dojotoolkit.org/nightly/dojotoolkit/
witcheryne 发表于2010年12月5日 22:09:03  IP:58.24.53.*举报回复删除
CometD 在tomcat下用过么?他的后台实现基于jetty的Continuation... tomcat没有相关支持.. Tomcat 6 开始提供 nio 实现, 提供了CometProcsser接口来实现Comet相关功能,但是文档就一个例子,很难理解。 dojotoolkit 发表于2010年12月7日 12:51:24  IP:220.248.0.*举报回复删除
回复 witcheryne:还真没用过,如果你有任何经验,欢迎分享
witcheryne 发表于2010年12月8日 9:29:28  IP:116.226.72.*举报回复删除
回复 dojotoolkit:这个没问题... 看了你的文章,对dojo很感兴趣, 近期项目打算采用dojo。 不过以前的项目采用的是jquery, 有很多遗留代码,不知道dojo能不能跟jquery进行集成. 我google半天也没找到什么有用的内容.发表评论表 情:          评论内容: 用 户 名:登录 注册 匿名评论 匿名用户验 证 码:  重新获得验证码
  热门招聘职位荷兰互联网公司诚聘Web(Rails)开发工程师【重庆大龙网】高薪诚聘中高级软件工程师美资高薪诚聘软件开发及数据库人才【新迪数字】高薪诚聘JAVA项目软件架构师、JAVA项目主管!!【尚品网】诚招软件开发工程师【UniQlick】【8K-12K】急招Java工程师、技术工程师、数据分析师【 CSDN】高薪诚聘:java、运营、就业、商务策划经理、网站编辑!【武汉亨通科技】高薪诚聘项目经理、高级软件工程师,邀您加盟!【careerfocus】科锐福克斯猎头公司强悍猎聘IT人才!【沃尔玛中国】信息系统部急聘IT英才(上海,深圳)!!!【融资城】投融资平台高薪诚聘技术总监、产品经理等【搜狐公司】海量技术职位火热招聘中!荷兰互联网公司诚聘Web(Rails)开发工程师【重庆大龙网】高薪诚聘中高级软件工程师美资高薪诚聘软件开发及数据库人才【新迪数字】高薪诚聘JAVA项目软件架构师、JAVA项目主管!!【尚品网】诚招软件开发工程师【UniQlick】【8K-12K】急招Java工程师、技术工程师、数据分析师【 CSDN】高薪诚聘:java、运营、就业、商务策划经理、网站编辑!【武汉亨通科技】高薪诚聘项目经理、高级软件工程师,邀您加盟!【careerfocus】科锐福克斯猎头公司强悍猎聘IT人才!【沃尔玛中国】信息系统部急聘IT英才(上海,深圳)!!!【融资城】投融资平台高薪诚聘技术总监、产品经理等【搜狐公司】海量技术职位火热招聘中! 公司简介|招贤纳士|广告服务|银行汇款帐号|联系方式|版权声明|法律顾问|问题报告
北京创新乐知信息技术有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
江苏乐知网络技术有限公司 提供商务支持
 Email:webmaster@csdn.net
Copyright © 1999-2010, CSDN.NET, All Rights Reserved
 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dojotoolkit/archive/2010/11/25/6035279.aspx