1.介绍
为了让Web应用能够和服务器进程之间保持双向通信,这里介绍WebSocket接口。
2.一致性要求(略)
3.术语(略)
4.WebSocket接口
(代码略)
WebSocket(url, protocols)构造函数可以传入1-2个参数。第一个参宿指定要连接的URL。第二个参数如果声明,可以是一个字符串或者是一个字符串数组。如果是一个字符串,它就相当于一个仅包含那一个字符串的数组。如果第二个参数省略,它就相当于一个空数组【也就是说不论第二个参数传入的是什么,都会当作一个字符串数组处理】。每一个数组中的字符串都是一个子协议名。只有当服务器声明其已经选择了其中一个子协议的时候连接才能建立。所有子协议名必须符合如下要求:这些字符串要包含WebSocket协议声明头部的Sec-WebSocket-Protocol的内容①。
当WebSocket()构造函数被调用时,用户代理必须执行如下步骤:
(1)从url参数中解析出URL的各个组件,从而获得主机、端口、资源名和安全协议(host, port, resource name, and secure)。如果这个过程失败了,就会抛出SyntaxError异常并且终止下面的步骤。
(2)如果secure是空,但是原来的进入脚本有一个模式组建其本身就是一个安全协议,比如HTTPS,那么就抛出SecurityError异常。(If secure is false but the origin of the entry script has a scheme component that is itself a secure protocol, e.g. HTTPS, then throw a SecurityError exception.)
(3)如果参数中的使用端口被用户代理设置为禁止访问的,那么就会抛出SecurityError异常。端口80和443不应该被禁止访问,包括secure是false的情况下443端口不能禁止访问,secure是true的时候80端口不能禁止访问【这里是说,WebSocket有两种形式,ws是不带安全协议的,默认使用80端口,wss是带安全协议的,默认使用443端口,但是即便使用的协议不需要对应的端口,也不能禁止访问443和80这两个端口】。
(4)如果没有声明protocols参数,让其成为一个空数组。否则,如果protocols参数是一个字符串,就让其变成包含这个字符串的数组。
(5)如果protocols参数中的任何一个变量被声明了超过以此,或者没有满足①的需求,就抛出SyntaxError异常并且终止下面的步骤。
(6)Let origin be the ASCII serialization of the origin of the entry script, converted to ASCII lowercase.
(7)返回一个新的WebSocket对象,并且在后台程序中继续执行下面的步骤。
(8)建立一个包含给出的host, port, resource name, and secure以及protocols列表,并且一个空的扩展(extensions)列表和origin的WebSocket连接。头部要想发送正确的cookies必须使用Cookie头,其中的值是通过用户存储的cookie值以及url计算出来的。出于这些目的,这不是一个没有HTTP协议的API。
在“WebSocket建立连接算法”执行期间,当用户代理验证服务器的响应时,如果从服务器收到的状态码不是101,用户代理必须终止这次WebSocket连接。
警告!这里使用HTTP处理可能会对浏览器上下文环境造成严重的安全隐患。例如,设想一个主机是使用WebSocket在一个路径上建立的服务器,一个开放的HTTP重定向指向另一个路径。突然,任何被指定了一个特定的WebSocket URL的脚本都可以进入这个服务并和其他的主机在网上进行沟通,即时脚本检查了URL为正确的主机名。
注意:如果WebSocket连接算法执行失败了,会触发WebSocket连接失败算法,这个算法会执行关闭WebSocket连接的算法,这就会将WebSocket连接关闭,触发close事件,执行步骤如下面所描述的。
当脚本的全局对象是Window对象或者是一个通过WorkerUtils接口实例化的对象时,这个构造函数必须是可见的。
url属性必须是从为构造函数传递的URL解析出来的。
readyState属性表示了连接的状态,它有如下几个值:
CONNECTING,对应的值是0,表示连接还没有被建立;
OPEN,对应的值是1,表示WebSocket连接已经建立了,并且可以进行通信;
CLOSING,对应值是2,表示连接正在进行关闭握手,或者close()方法已经被调用;
CLOSED,对应值是3,表示连接已经被关闭或者无法打开连接。
当WebSocket实例化对象被创建时,它的readyState值必须设定为CONNESTING。
extensions属性初始值必须是一个空的字符串。当WebSocket连接建立后,它的值可以按照如下规则改变。
注意:如果服务器选择了扩展,extension属性返回的服务器选择的扩展。(目前这个字段一直是一个空字段)
protocol属性初始化必须是一个空的字符串。当WebSocket连接建立后,它的值可以按照如下规则改变。
注意:如果服务器指定了子协议,protocol属性返回服务器选择的子协议。
close()方法必须按照下面的步骤执行:
(1)如果这个方法传递了第一个参数但是不等于1000或者不在3000到4999之内,抛出InvalidAccessError异常并终止下面的步骤。
(2)如果传入了第二个参数,就执行下面的子步骤:
①让raw reason成为方法的第二个参数
②(后面省略)
(3)执行下面第一个匹配到的步骤
①如果readyState属性是CLOSING或者CLOSED,什么也不发生。
②如果WebSocket连接还没有建立,终止WebSocket连接的建立并且将readyState的属性值设置为CLOSING。
③如果WebSocket的关闭握手还没有开始,启动WebSocket的关闭握手,并且将readyState设置成CLOSING。如果传递了第一个参数,那么WebSocket关闭报文使用的状态码必须是第一个参数指定的整数。如果第二个参数也声明了,必须在关闭报文的状态码后面给出reason。
④其他情况,将readyState属性值设置成CLOSING。