文章目录

  • 第十五章 Caché WebSocket
  • 使用WebSockets (RFC 6455)
    • Short Polling 短轮询
    • Long Polling 长轮询
    • HTTP Streaming HTTP流
  • WebSockets协议
    • 浏览器支持
    • 服务器的支持
    • 协议的细节
  • WebSockets客户端代码(JavaScript)
    • 创建WebSocket
    • WebSocket事件
    • WebSocket方法
  • WebSockets服务器代码(CSP)
    • WebSocket事件
    • `WebSocket`方法
    • WebSocket属性
  • websocket服务器示例
  • WebSockets服务器异步操作

第十五章 Caché WebSocket

使用WebSockets (RFC 6455)

web是围绕请求/响应范例构建的:客户机向服务器发送请求,服务器通过向客户机发送响应进行响应。此范式和HTTP本身不允许此通信协议的反向形式,即服务器与客户机启动请求/响应周期。已经开发了许多技术来解决了这个问题,即服务器可以启动与客户机的对话。这些技术通常被称为基于推送或 comet-based的技术,它们都存在不适合在web基础设施上进行全面部署的问题。目前使用的三种主要技术如下所述。

Short Polling 短轮询

使用这种技术,客户端定期发送HTTP请求来检测服务器状态的变化,服务器被编程为立即响应。空响应表示没有变化。

问题:

  • 轮询频率(和响应能力)受到客户机可以容忍的刷新延迟的限制。
  • 每个请求都是一个完整的HTTP请求/响应往返过程,这会导致大量的HTTP流量,而这又会给服务器和网络基础设施带来无法接受的负担
  • 每个消息交换都承载着HTTP协议的开销,如果消息大小超过了最大传输单元(MTU)(通常是以太网的1500字节),则会特别繁重。

Long Polling 长轮询

使用这种技术,客户端发送HTTP请求,但服务器只在需要通知客户端更改时才响应。客户端通常在服务器发送响应消息时发送另一个“长轮询”请求。

问题:

  • 每个请求都是完整的HTTP请求/响应往返,尽管这种技术涉及的HTTP通信量比短轮询少。
  • 还有维护持久连接的负担。
  • 每个消息交换都带有HTTP协议的开销。
  • 超时可能会对该技术的成功产生不利影响。

HTTP Streaming HTTP流

这种技术利用了HTTP协议在客户端和服务器之间保持持久(或“KeepAlive”)连接的能力。客户端发送一个HTTP请求,该请求永久保持打开状态,只有在需要通知客户端更改时,服务器才会响应。服务器在发送响应消息后不终止连接,客户机等待来自服务器的下一条消息(或向服务器发送自己的消息)。

问题:

  • 整个客户机/服务器交换是在一个HTTP请求/响应往返过程中构建的,并不是所有服务器都支持这种方式。
  • 这种技术的成功可能会受到代理和网关等中介行为的不利影响。(曾经手机上设置代理IP就不能正常访问请求)
  • 任何一方都没有义务立即向另一方提交部分回复。
  • 客户端缓冲方案可能会对该技术产生不利影响。
  • 超时可能会对该技术产生负面影响。

WebSockets协议

WebSockets协议(RFC 6455)通过在客户端和服务器之间提供一个全双工的面向消息的通信通道,解决了允许服务器主动将消息推送到客户端的基本需求。该协议被设计为在客户端和服务器之间已经建立的标准TCP通道上操作,因此是安全的。换句话说,已经使用的通道支持web浏览器和web服务器之间的HTTP协议。

WebSockets协议及其API由W3C标准化,客户端部分包含在HTML 5中。

中介体(如代理和防火墙)应该设置成知道(并支持)WebSockets协议。

浏览器支持

在为WebSockets协议创建最终标准的过程中,已经进行了几次迭代,每一次都有不同程度的浏览器支持。历史概述如下。

  • Hixie-75:
  1. Chrome 4.0+5.0, Safari 5.0.0
  • HyBi-00/Hixie-76:
  1. Chrome 6.0-13.0, Safari 5.0.2+5.1, Firefox 4.0 (disabled), Opera 11 (disabled)
  • HyBi-07+:
  1. Chrome 14.0, Firefox 6.0, IE 9 (via Silverlight extension)
  • HyBi-10:
  1. Chrome 14.0+15.0, Firefox 7.0+8.0+9.0+10.0, IE 10 (via Windows 8 developer preview)
  • HyBi-17/RFC 6455
  1. Chrome 16
  2. Safari 6
  3. Firefox 11
  4. Opera 12.10/Opera Mobile 12.1
  5. IE 10
    最后突出显示的部分对于开发可移植web应用程序是最重要的。

服务器的支持

可以说,面向服务器的基于javascriptNode.js技术提供了最复杂、目前最成熟的WebSockets协议实现。WebSockets一直与Node.js紧密联系在一起。但是,其他web服务器技术正在迅速赶上来,所有主要web服务器的最新版本现在都提供了WebSockets支持,如下所示。

  • Node.js
  1. 全版本
  • Apache v2.2
  • IIS v8.0
  1. Windows 8 and Windows Server 2012
  • Nginx v1.3
  • Lighttpd
    高亮显示的部分对于使用CSP开发可移植web应用程序来说是最重要的。

协议的细节

创建WebSocket涉及到客户端和服务器之间的有序消息交换。首先,必须进行WebSocket握手。握手基于并类似于HTTP消息交换,因此它可以毫无问题地通过现有的HTTP基础设施传递。

  • 客户端发送WebSocket连接的握手请求。
  • 服务器发送握手响应(如果可以的话)。

web服务器识别握手请求消息中的传统HTTP头结构,并向客户机发送类似构造的响应消息,表明它支持WebSocket协议。如果双方都同意,那么通道将从HTTP (http://)切换到WebSockets协议(ws://)

当协议成功切换后,通道允许客户端和服务器之间的全双工通信。

单个消息的数据帧很少。

典型的来自客户端的WebSocket握手消息

GET /csp/user/MyApp.MyWebSocketServer.cls HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://localhost

典型的WebSocket握手消息来自服务器

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

请注意客户端握手消息如何请求将协议从HTTP升级到WebSocket。还要注意客户机(secwebsocket - key)和服务器(secwebsocket - accept)之间唯一密钥的交换。

WebSockets客户端代码(JavaScript)

在浏览器环境中,WebSocket协议的客户端是用JavaScript代码实现的。标准教科书详细描述了使用模型。本文件将简要介绍基本知识。

创建WebSocket

  • 第一个参数表示标识WebSocket应用程序服务器端的URL
  • 第二个参数是可选的,如果有,指定服务器必须支持的子协议,以便WebSocket连接成功。
var ws = new WebSocket(url, [protocol]);

例子:

ws = new WebSocket(((window.location.protocol == "https:")? "wss:" : "ws:") \+ "//" + window.location.host+ /csp/user/MyApp.MyWebSocketServer.cls);
  $("#conUrl").val((window.location.protocol == "https:" ? "wss:" : "ws:") + "//" + window.location.host + "/dthealth/web/PHA.COM.WebSocket.cls" )

请注意,如何将协议定义为wswss,这取决于是否使用SSL/TLS保护底层传输。

只读属性ws.readyState定义连接的状态。它可以取以下值之一:

  • 0 连接尚未建立。
  • 1 连接已经建立,通信是可能的。
  • 2 连接以结束握手为准。
  • 3 连接已关闭或无法打开。

只读属性ws.bufferedAmount定义UTF-8文本的字节数,使用send()方法排队。

WebSocket事件

以下事件是可用的。

  • ws.onopen 在建立套接字连接时打触发。
  • ws.onmessage 当客户机从服务器接收数据时触发。

event.data中接收的数据。

  • ws.onerror 当通信中发生错误时触发。
  • ws.onclose 当连接关闭时触发。

WebSocket方法

以下是可用的方法。

  • ws.send(data) 将数据传输到客户端。
  • ws.close() 关闭连接。

WebSockets服务器代码(CSP)

实现WebSocket服务器的基本Caché 类是%CSP.WebSocket

当客户机请求一个WebSocket连接时,初始HTTP请求(初始握手消息)指示CSP引擎初始化应用程序的WebSocket服务器。WebSocket服务器是请求URL中指定的类。

例如,如果您的WebSocket服务器被称为 MyApp.MyWebSocketServer 的设计是在用户名称空间中操作,然后用于请求WebSocket连接的URL是:

/csp/user/MyApp.MyWebSocketServer.cls
ws://127.0.0.1/dthealth/web/PHA.COM.WebSocket.cls

WebSocket事件

WebSocket服务器的实现是从基本的%CSP.WebSocket类派生出来的。实现以下事件的响应有三个关键方法。注意,CSP会话在调用任何这些方法之前都是解锁的。

  • OnPreServer (optional)
    使用此方法调用应该在WebSocket服务器建立之前执行的代码。必须在这里更改SharedConnection属性。
Method OnPreServer() As %Status
{//设置 SharedConnection属性set ..SharedConnection=1if (..WebSocketID'=""){set ^CacheTemp.Chat.WebSockets(..WebSocketID)=""}else {set ^CacheTemp.Chat.Error($INCREMENT(^CacheTemp.Chat.Error),"no websocketid defined")=$HOROLOG }q $$$OK
}
  • Server (Mandatory)
    WebSocket服务。 这是WebSocket应用程序的服务器端实现。可以使用Read()Write()方法与客户机交换消息。使用EndServer()方法从服务器端优雅地关闭WebSocket
  • OnPostServer (optional)
    使用此方法调用应该在WebSocket服务器关闭后执行的代码。

WebSocket方法

提供了以下方法

Method Read(ByRef len As %Integer = 32656,ByRef sc As %Status,timeout As %Integer = 86400) As %String

该方法从客户端读取len字符。如果调用成功,状态(sc)将返回$$$OK,否则将返回以下错误代码之一:

  • $$$CSPWebSocketTimeout 读取已超时。
  • $$$CSPWebSocketClosed 客户端已经终止了WebSocket
Method Write(data As %String) As %Status

此方法将数据写入客户端。

Method EndServer() As %Status

此方法通过关闭与客户端的连接来优雅地结束WebSocket服务器。

Method OpenServer(WebSocketID As %String = "") As %Status

此方法打开现有的WebSocket服务器。只有异步操作的WebSocket (SharedConnection=1)可以使用此方法访问。

WebSocket属性

提供了以下属性:

SharedConnection (default: 0)

此属性确定客户端和WebSocket服务器之间的通信是通过专用网关连接进行,还是通过共享连接池异步进行。必须在OnPreServer()方法中设置此属性,可以按如下方式设置:

  • SharedConnection=0 WebSocket服务器通过专用网关连接与客户端进行同步通信。在这种操作模式下,主机连接实际上是应用程序的WebSocket服务器的“私有”连接

  • SharedConnection=1 WebSocket服务器通过共享网关连接池与客户端异步通信。

  • WebSocketID 此属性表示WebSocket的唯一标识。

  • SessionId 此属性表示用于创建WebSocket的托管CSP会话ID

  • BinaryData 此属性指示网关绕过将传输的数据流解释为UTF-8编码文本的功能,并在WebSocket帧头中设置适当的二进制数据字段。

在将二进制数据流写入客户机之前,应该将该值设置为1。例如:

Set ..BinaryData = 1

websocket服务器示例

以下简单的WebSocket服务器类接受来自客户机的传入连接,并简单地回显接收到的数据。超时设置为10秒,每次Read()方法超时时,客户端都会写入一条消息。这说明了支持WebSockets的关键概念之一:从服务器与客户端启动消息交换。

最后,如果客户端(即用户)发送了字符串exit, WebSocket就会优雅地关闭。

Method OnPreServer() As %Status
{Quit $$$OK
}Method Server() As %Status
{Set timeout=10For  {Set len=32656Set data=..Read(.len, .status, timeout)If $$$ISERR(status) {If $$$GETERRORCODE(status) = $$$CSPWebSocketClosed {Quit}If $$$GETERRORCODE(status) = $$$CSPWebSocketTimeout {Set status=..Write(“Server timed-out at “_$Horolog)}}else {If data="exit" QuitSet status=..Write(data)}}Set status=..EndServer()Quit $$$OK
}Method OnPostServer() As %Status
{Quit $$$OK
}

WebSockets服务器异步操作

前一节给出的示例演示了通过专用Caché 连接与客户机同步操作的WebSocket服务器。当这样的连接建立后,它会在网关系统状态表单的状态列中标记为WebSocket。使用这种模式,WebSocket可以在托管CSP会话的安全上下文中操作,并且可以轻松地访问与该会话关联的所有属性。

使用异步操作模式(SharedConnection=1),一旦创建了WebSocket对象,与客户端的后续对话就会在共享连接池中进行,此时主机连接就会被释放:来自客户机的消息通过常规的网关连接池到达Caché ,而发送到客户机的消息则通过在网关和Caché 之间建立的服务器连接池分派。

在异步模式下,WebSocket服务器与主CSP会话分离:SessionId属性持有托管会话ID的值,但是不会自动创建会话对象的实例。只需在OnPreServer()方法中设置SharedConnection属性,就可以异步运行前面给出的示例。但是,没有必要将Caché 进程与WebSocket永久关联起来。 Server()可以退出(主机进程停止),而不需要关闭WebSocket。如果保留了WebSocketID,则可以随后在不同的Caché 进程中打开WebSocket,并恢复与客户机的通信。

例如:

Class PHA.COM.YX.WebSocket Extends %CSP.WebSocket
{Method OnPreServer() As %Status
{d ##class(PHA.OP.MOB.Test).Save(..WebSocketID)Set SharedConnection = 1Quit $$$OK
}Method Server() As %Status
{Quit $$$OK
}Method OnPostServer() As %Status
{Quit $$$OK
}}

注意,在OnPreServer()方法中保留WebSocketID供后续使用。还要注意,OnPreServer()方法中SharedConnection属性的设置以及服务器()方法的退出。

随后检索WebSocketID:

Set WebSocketID = MYAPP.RETRIEVE()

与客户重新建立联系:

Set ws=##class(%CSP.WebSocketTest).%New()
Set %status = ws.OpenServer(WebSocketID)

给客户端读写

Set %status=ws.Write(message)
Set data=ws.Read(.len, .%status, timeout)

最后,从服务器端关闭WebSocket:

Set %status=ws.EndServer()

第十五章 Caché WebSocket相关推荐

  1. 第七十五章 Caché 函数大全 $XECUTE 函数

    文章目录 第七十五章 Caché 函数大全 $XECUTE 函数 大纲 参数 描述 参数 code paramlist 示例 第七十五章 Caché 函数大全 $XECUTE 函数 执行指定的命令行. ...

  2. 第二十五章 Caché 变量大全 $ZB 变量

    文章目录 第二十五章 Caché 变量大全 $ZB 变量 大纲 描述 文件结束行为 从终端或文件读取 命令行上的$ZB `$ZB`,带磁带I/O 第二十五章 Caché 变量大全 $ZB 变量 包含当 ...

  3. 第十九章 Caché 函数大全 $INCREMENT 函数

    文章目录 第十九章 Caché 函数大全 $INCREMENT 函数 大纲 参数 描述 参数 variable num INCREMENT或INCREMENT或INCREMENT或SEQUENCE $ ...

  4. java十五章_java:第十五章

    第十五章 字符串1.字符串(String)的定义 String str="内容"; String str=new String(); //内容为null String str=ne ...

  5. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引...

    Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 原文:Introduction to 3 ...

  6. Gradle 1.12用户指南翻译——第三十五章. Sonar 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  7. Visual C++ 2008入门经典 第十五章 在窗口中绘图

    /*第十五章 在窗口中绘图 主要内容: 1 Windows为窗口绘图提供的坐标系统 2 设置环境及其必要性 3 程序如何以及在窗口中绘图 4 如何定义鼠标消息的处理程序 5 如何定义自己的形状类 6 ...

  8. 第十五章 shell正则表达式

    第十五章 shell正则表达式 见图片 Shell正则表达式 正则表达式的分类 基本的正则表达式(Basic Regular Expression 又叫Basic RegEx 简称BREs) 扩展的正 ...

  9. 第二十五章补充内容 3 assert()宏

    //第二十五章补充内容 3 assert()宏 //有的编译器还提供了assert()宏,这个宏在许多书中被翻译为断言,它的作用是当assert()的参数为真时,返回真,假如参数值为假,那么它将执行某 ...

最新文章

  1. 基于注解的DWR使用
  2. tomcat进程意外退出的问题分析
  3. jsp内置对象与el内置对象
  4. boost::uuid模块实现宽流存档测试序列化 uuid的测试程序
  5. iOS Block全面分析
  6. 码农30岁后的体检——你最需要的是直面的勇气
  7. Sql为什么连接不上服务器上的数据库
  8. XML类型的SQL参数
  9. 为什么 npm 要为每个项目单独安装一遍 node_modules?
  10. 【BZOJ】3396: [Usaco2009 Jan]Total flow 水流 (最大流)
  11. 阿里云网盘来了,来搭建自己“免费“私人网盘
  12. 一个都不能少:全面认识IE插件
  13. Arduino UNO步进电机控制
  14. 干货满满!亲测国内四大AI智能抠图网站
  15. flink Flink在监控流计算中的应用
  16. Linux之core dumped出错原因及位置分析
  17. Google 机器学习术语表
  18. Adobe是什么软件?
  19. 阿里云建站产品有哪些?如何选择?
  20. 图像数据增强及其对应的标签扩充

热门文章

  1. Photoshop使用背景图层的方法
  2. 计算机显示器未响应,电脑开机显示器没反应的故障排除方法
  3. 03.07:BT下载&区块链技术
  4. 详解sklearn——CountVectorizer
  5. 【NLP】语法、文法、句法、词法概念的区别
  6. 七张图,学会做有价值的经营分析
  7. 第五届四川省职工职业技能大赛决赛计算机程序设计员技术文件大纲
  8. 在图片上涂鸦(其实就是乱画 O(∩_∩)O)
  9. 'BMap' is not defined 解决方案,亲测有效
  10. MAC获取公钥的步骤