一、概述

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头部:

    1. <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>

    加载脚本后,可以与SockJS服务器建立连接。下面是一个简单的例子:

    1. var sock = new SockJS('https://mydomain.com/my_prefix');
    2. sock.onopen = function() {
    3. console.log('open');
    4. sock.send('test');
    5. };
    6. sock.onmessage = function(e) {
    7. console.log('message', e.data);
    8. sock.close();
    9. };
    10. sock.onclose = function() {
    11. console.log('close');
    12. };

    四、SockJS客户端API

    与“WebSocket”API类似,“SockJS”构造函数接受一个或多个参数:

    1. 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连接使用不同的子域。

参考文档

https://github.com/sockjs/sockjs-client