一、概述
SockJS是一个浏览器JavaScript库,提供类似WebSocket的对象。SockJS为您提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域的通信通道。
Under the hood SockJS首先尝试使用原生WebSocket。如果失败了,它可以使用各种特定于浏览器的传输协议,并通过类似WebSocket的抽象来呈现它们。
SockJS适用于所有现代浏览器和不支持WebSocket协议的环境,例如,在限制性的公司代理之后。
SockJS客户端确实需要对应的服务器:
- SockJS节点是一个用于Node.js的SockJS服务器。
理念:
- API应该尽可能地遵循HTML5 Websockets API。
- 所有传输必须支持现成的跨域连接。建议您将SockJS服务器托管在与主网站不同的服务器上。
- 每个主要浏览器至少支持一种流媒体协议。
- 流式传输应该跨域工作,并且应该支持cookie(用于基于cookie的粘性会话)。
- 轮询传输被用作旧浏览器和限制性代理后面的主机的后备。
- 连接建立应该快速且轻量级。
内部无闪存(无需打开843端口,该端口无法通过代理工作,无需托管“crossdomain.xml”,无需等待3秒钟以检测问题)
二、SockJS家族
SockJS-client JavaScript client library
- SockJS-node Node.js server
- SockJS-erlang Erlang server
- SockJS-cyclone Python/Cyclone/Twisted server
- SockJS-tornado Python/Tornado server
- SockJS-twisted Python/Twisted server
- SockJS-aiohttp Python/Aiohttp server
- Spring Framework Java client & server
- vert.x Java/vert.x server
- Xitrum Scala server
- Atmosphere Framework JavaEE Server, Play Framework, Netty, Vert.x
- Actix SockJS Rust Server, Actix Framework
正在进行的工作:
- SockJS-ruby
- SockJS-netty
- SockJS-gevent (SockJS-gevent fork)
- pyramid-SockJS
- wildcloud-websockets
- wai-SockJS
- SockJS-perl
- SockJS-go
syp.biz.SockJS.NET - .NET port of the SockJS client
三、启动
SockJS模仿WebSockets API,但有一个SockJS Javascript对象代替WebSocket。
首先,需要加载SockJS JavaScript库。例如,您可以将其放在HTML头部:<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
加载脚本后,可以与SockJS服务器建立连接。下面是一个简单的例子:
var sock = new SockJS('https://mydomain.com/my_prefix');
sock.onopen = function() {
console.log('open');
sock.send('test');
};
sock.onmessage = function(e) {
console.log('message', e.data);
sock.close();
};
sock.onclose = function() {
console.log('close');
};
四、SockJS客户端API
与“WebSocket”API类似,“SockJS”构造函数接受一个或多个参数:
var sockjs = new SockJS(url, _reserved, options);
如果需要,url可以包含查询字符串。
其中,options是一个散列,可以包含:服务器(字符串)
- 要附加到url以进行实际数据连接的字符串。默认为随机的4位数字。
- 传输(字符串或字符串数组)
- 有时禁用一些回退传输是有用的。此选项允许您提供SockJS可能使用的传输列表。默认情况下,将使用所有可用的传输。
- sessionId(数字或函数)
- 客户端和服务器都使用会话标识符来区分连接。如果将此选项指定为数字,SockJS将使用其随机字符串生成器函数生成N个字符长的会话ID(其中N对应于sessionId指定的数字)。将此选项指定为函数时,函数必须返回随机生成的字符串。每次SockJS需要生成会话id时,它都会调用此函数并直接使用返回的字符串。如果未指定此选项,默认情况下使用默认的随机字符串生成器生成8个字符长的会话ID。
- 超时(数字)
- 指定用于传输连接的最小超时(以毫秒为单位)。默认情况下,这是基于测量的RTT和预期往返次数动态计算的。此设置将建立最小值,但如果计算的超时值更高,则将使用该值。
尽管“SockJS”对象试图模仿“WebSocket”行为,但不可能支持其所有功能。SockJS的一个重要限制是,一次不允许打开多个与单个域的SockJS连接。这种限制是由浏览器中传出连接的限制造成的——通常浏览器不允许打开到单个域的两个以上传出连接。单个SockJS会话需要这两个连接——一个用于下载数据,另一个用于发送消息。同时打开第二个SockJS会话很可能会阻塞,并可能导致两个会话都超时。
一次打开多个SockJS连接通常是不好的做法。如果绝对必须这样做,可以使用多个子域,为每个SockJS连接使用不同的子域。