SockJS是一个浏览器JavaScript库,提供了一个类似websocket的对象。SockJS为您提供了一个连贯的,跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟,全双工,跨域通信通道。
实际上,SockJS首先尝试使用本地WebSockets。如果失败了,它可以使用各种特定于浏览器的传输协议,并通过类似websocket的抽象来表示它们。
SockJS旨在适用于所有现代浏览器和不支持WebSocket协议的环境——例如,在限制性的公司代理之后。
SockJS-client确实需要一个对应的服务器:
原则:
订阅SockJS邮件列表进行讨论和支持。
进行中的工作:
SockJS 模仿 WebSockets API,但不是 WebSocket,而是 SockJS Javascript 对象。
首先,您需要加载 SockJS JavaScript 库。 例如,你可以把它放在你的 HTML 头部:
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
After the script is loaded you can establish a connection with the SockJS server. Here’s a simple example:
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');
};
与WebSocket API 类似,SockJS构造函数采用一个或多个参数:
var sockjs = new SockJS(url, _reserved, options);
url 可以包含一个查询字符串,如果需要的话。
其中 options 是一个散列,它可以包含:
server (字符串)
要附加到实际数据连接的 url 的字符串。 默认为随机的 4 位数字。
transports (字符串 或者 字符串数组)
有时禁用一些后备传输很有用。 此选项允许您提供 SockJS 可能使用的传输列表。 默认情况下,将使用所有可用的传输。
sessionId (数字 或者 函数)
客户端和服务器都使用会话标识符来区分连接。如果您将此选项指定为数字,SockJS 将使用其随机字符串生成器函数生成 N 个字符长的会话 ID(其中 N 对应于 sessionId 指定的数字)。当您将此选项指定为一个函数时,该函数必须返回一个随机生成的字符串。每次 SockJS 需要生成会话 ID 时,它都会调用此函数并直接使用返回的字符串。如果不指定此选项,则默认使用默认的随机字符串生成器生成 8 个字符的长会话 ID。
timeout (数字)
指定用于传输连接的最小超时时间(以毫秒为单位)。默认情况下,这是根据测量的 RTT 和预期往返次数动态计算的。此设置将建立一个最小值,但如果计算出的超时值更高,则会使用该值。
虽然 SockJS 对象试图模拟 WebSocket 行为,但不可能支持它的所有功能。SockJS 的一个重要限制是您不允许一次打开一个以上的 SockJS 连接到一个域。此限制是由传出连接的浏览器内限制引起的 - 通常浏览器不允许打开两个以上的传出连接到单个域。一个 SockJS 会话需要这两个连接 - 一个用于下载数据,另一个用于发送消息。同时打开第二个 SockJS 会话很可能会阻塞,并可能导致两个会话超时。
一次打开多个 SockJS 连接通常是一种不好的做法。如果你绝对必须这样做,你可以使用多个子域,为每个SockJS连接使用不同的子域。
译者白石注: 现代的浏览器早已支持同一个域可以打开多个连接了.
| Browser | Websockets | Streaming | Polling |
|---|---|---|---|
| IE 6, 7 | no | no | jsonp-polling |
| IE 8, 9 (cookies=no) | no | xdr-streaming † | xdr-polling † |
| IE 8, 9 (cookies=yes) | no | iframe-htmlfile | iframe-xhr-polling |
| IE 10 | rfc6455 | xhr-streaming | xhr-polling |
| Chrome 6-13 | hixie-76 | xhr-streaming | xhr-polling |
| Chrome 14+ | hybi-10 / rfc6455 | xhr-streaming | xhr-polling |
| Firefox <10 | no ‡ | xhr-streaming | xhr-polling |
| Firefox 10+ | hybi-10 / rfc6455 | xhr-streaming | xhr-polling |
| Safari 5.x | hixie-76 | xhr-streaming | xhr-polling |
| Safari 6+ | rfc6455 | xhr-streaming | xhr-polling |
| Opera 10.70+ | no ‡ | iframe-eventsource | iframe-xhr-polling |
| Opera 12.10+ | rfc6455 | xhr-streaming | xhr-polling |
| Konqueror | no | no | jsonp-polling |
有时您可能希望从“file://”地址提供您的 html - 用于开发或者如果您正在使用 PhoneGap 或类似技术。但是由于跨源策略,从“file://”提供的文件没有源,这意味着某些 SockJS 传输将无法工作。由于这个原因,SockJS 传输表与通常不同,主要区别是:
| Browser | Websockets | Streaming | Polling |
|---|---|---|---|
| IE 8, 9 | no | iframe-htmlfile | iframe-xhr-polling |
| Other | same as above | iframe-eventsource | iframe-xhr-polling |
| Transport | References |
|---|---|
| websocket (rfc6455) | [rfc 6455]2 |
| websocket (hixie-76) | [draft-hixie-thewebsocketprotocol-76]3 |
| websocket (hybi-10) | [draft-ietf-hybi-thewebsocketprotocol-10]4 |
| xhr-streaming | Transport using [Cross domain XHR]5 [streaming]6 capability (readyState=3). |
| xdr-streaming | Transport using [XDomainRequest]1 [streaming]6 capability (readyState=3). |
| eventsource | [EventSource/Server-sent events]7. |
| iframe-eventsource | [EventSource/Server-sent events]7 used from an [iframe via postMessage]8. |
| htmlfile | [HtmlFile]9. |
| iframe-htmlfile | [HtmlFile]9 used from an [iframe via postMessage]8. |
| xhr-polling | Long-polling using [cross domain XHR]5. |
| xdr-polling | Long-polling using [XDomainRequest]1. |
| iframe-xhr-polling | Long-polling using normal AJAX from an [iframe via postMessage]8. |
| jsonp-polling | Slow and old fashioned [JSONP polling]10. This transport will show “busy indicator” (aka: “spinning wheel”) when sending data. |
虽然 SockJS 的主要目的是启用浏览器到服务器的连接,但也可以从外部应用程序连接到 SockJS。任何符合 0.3 协议的 SockJS 服务器都支持原始 WebSocket url。测试服务器的原始WebSocket url如下所示:
您可以将任何符合 WebSocket RFC 6455 标准的 WebSocket 客户端连接到此 url。这可以是命令行客户端、外部应用程序、第三方代码甚至是浏览器(尽管我不知道您为什么要这样做)。
您应该使用支持服务器使用的协议的 sockjs-client 版本。 例如:
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
关于服务器端部署技巧,特别是关于负载平衡和会话粘连的技巧,请参阅SockJS-node readme。
SockJS-client需要node.js来运行测试服务器和简化JavaScript。如果你想使用SockJS-client源代码,签出git repo并遵循以下步骤:
cd sockjs-client
npm install
要生成JavaScript,运行:
gulp browserify
要生成最小化的JavaScript,运行:
gulp browserify:min
这两个命令都输出到 build 目录。
由以下机构提供的自动化测试:

编译 SockJS-client 后,您可能想检查您的更改是否通过了所有测试。
npm run test:browser_local
这将启动 karma 和测试支持服务器。
我们不打算解决各种浏览器怪癖:
jsonp-polling 传输在发送数据时会显示一个“纺车”(又名“忙指示器”)。onmessage 的全局函数可能不是一个好主意,因为它可以由内置的 postMessage API 调用。https://openbase.com/js/sockjs/documentation
通常 WebSockets 不能很好地与代理和负载均衡器一起使用。 在 Nginx 或 Apache 后面部署 SockJS 服务器可能会很痛苦。
幸运的是,一个优秀的负载均衡器HAProxy的最新版本能够代理WebSocket连接。我们建议将HAProxy作为前端负载均衡器,并使用它将 SockJS 流量与普通 HTTP 数据分开。查看示例 SockJS HAProxy 配置。
haproxy.cfg文件:
# Requires recent Haproxy to work with websockets (for example 1.4.16).
defaults
mode http
# Set timeouts to your needs
timeout client 5s
timeout connect 5s
timeout server 5s
frontend all 0.0.0.0:8888
mode http
timeout client 120s
option forwardfor
# Fake connection:close, required in this setup.
option http-server-close
option http-pretend-keepalive
acl is_sockjs path_beg /echo /broadcast /close
acl is_stats path_beg /stats
use_backend sockjs if is_sockjs
use_backend stats if is_stats
default_backend static
backend sockjs
# Load-balance according to hash created from first two
# directories in url path. For example requests going to /1/
# should be handled by single server (assuming resource prefix is
# one-level deep, like "/echo").
balance uri depth 2
timeout server 120s
server srv_sockjs1 127.0.0.1:9999
# server srv_sockjs2 127.0.0.1:9998
backend static
balance roundrobin
server srv_static 127.0.0.1:8000
backend stats
stats uri /stats
stats enable
该配置还展示了如何使用 HAproxy 平衡在多个 Node.js 服务器之间拆分流量。 您还可以使用 DNS 名称进行平衡。
再看看一个生产上的支持 Websocket 的 HAProxy 配置(haproxy.cfg):
global
maxconn 4096 # Total Max Connections. This is dependent on ulimit
nbproc 2
log 127.0.0.1 local1 notice
defaults
mode http
log global
frontend all 0.0.0.0:80
timeout client 86400000
default_backend www_backend
acl is_websocket hdr(Upgrade) -i WebSocket
acl is_websocket hdr_beg(Host) -i ws
acl host_bibliaolvaso hdr_sub(Host) -i bibliaolvaso.hu
acl host_todomvc hdr_sub(Host) -i todomvc
use_backend bibliaolvaso_backend if is_websocket host_bibliaolvaso
use_backend todomvc_backend if is_websocket host_todomvc
backend www_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
timeout server 86400000
timeout connect 4000
server nginx localhost:81
backend bibliaolvaso_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
timeout queue 5000
timeout server 86400000
timeout connect 5000
server bibliaolvaso localhost:7777
backend todomvc_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
timeout queue 5000
timeout server 86400000
timeout connect 5000
server todomvc localhost:3003
如果您计划部署多个SockJS服务器,则必须确保单个会话的所有HTTP请求都将命中同一个服务器。SockJS有两种机制可以实现这一点:
/resource/<server_number>/<session_id>/transport。 这对于支持基于前缀的关联(HAProxy 支持)的负载均衡器很有用。JSESSIONID cookie 由 SockJS 节点设置。 如果设置了该 cookie,许多负载平衡器会打开粘性会话。 此技术源自 Java 应用程序,其中通常需要粘性会话。 HAProxy 以及一些托管服务提供商(例如 CloudFoundry)确实支持这种方法。 为了在客户端启用此方法,请向 SockJS 构造函数提供 cookie:true 选项。SockJS 节点不会向应用程序公开 cookie。 这是故意这样做的,因为在 SockJS 中使用基于 cookie 的授权根本没有意义,并且会导致安全问题。
cookie是浏览器和http服务器之间的契约,由域名标识。如果浏览器为特定的域设置了cookie,它将把它作为所有http请求的一部分传递给主机。但是为了让各种传输工作,SockJS使用了一个中间人
基本上- cookie不适合SockJS模型。如果你想授权一个会话-在一个页面上提供一个唯一的令牌,首先通过SockJS连接发送它,并在服务器端验证它。本质上,这就是cookie的工作原理。
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
很高兴看到google代码:google-api-ruby-client项目,因为这对我来说意味着Ruby人员可以使用GoogleAPI-s来完善代码。虽然我现在很困惑,因为给出的唯一示例使用Buzz,并且根据我的实验,Google翻译(v2)api的行为必须与google-api-ruby-client中的Buzz完全不同。.我对“Explorer”演示示例很感兴趣——但据我所知,它并不是一个探索器。它所做的只是调用一个Buzz服务,然后浏览它已经知道的关于Buzz服务的事情。对我来说,Explorer应该让您“发现”所公开的服务和方法/功能,而不一定已经知道它们。我很想听听使用这个
我正在努力让google-api-ruby-clientgem按照这里的基本用法示例工作:基本用法require'google/apis/drive_v2'Drive=Google::Apis::DriveV2#Aliasthemoduledrive=Drive::DriveService.newdrive.authorization=...#SeeGoogleauthorSignetlibraries#SearchforfilesinDrive(firstpageonly)files=drive.list_files(q:"titlecontains'finances'")files
我正在尝试从googleAPI下载client_secret.json。我正在执行https://developers.google.com/gmail/api/quickstart/ruby中列出的步骤.使用此向导在GoogleDevelopersConsole中创建或选择项目并自动启用API。在左侧边栏中,选择同意屏幕。选择电子邮件地址并输入产品名称(如果尚未设置),然后单击“保存”按钮。在左侧边栏中,选择凭据并点击创建新客户端ID。选择应用程序类型已安装应用程序,已安装应用程序类型为其他,然后单击“创建客户端ID”按钮。点击新客户端ID下的下载JSON按钮。将此文件移动到您的工作
昨晚看到IDEA官推宣布IntelliJIDEA2023.1正式发布了。简单看了一下,发现这次的新版本包含了许多改进,进一步优化了用户体验,提高了便捷性。至于是否升级最新版本完全是个人意愿,如果觉得新版本没有让自己感兴趣的改进,完全就不用升级,影响不大。软件的版本迭代非常正常,正确看待即可,不持续改进就会慢慢被淘汰!根据官方介绍:IntelliJIDEA2023.1针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施,使得Maven导入更快,并且在打开项目时IDE功能更早地可用。由于后台提交检查,新版本提供了简化的提交流程。IntelliJIDEA
我正在为ruby使用googleapi,但不知道如何开始,请给我一个ABC示例,非常感谢? 最佳答案 如果您要创建服务帐户应用程序以访问GoogleAnalytics。通过https://code.google.com/apis/console向Google注册.在APIAccess选项卡上,单击CreateclientID,选择ServiceAccount。存储Google将生成的key文件,并记住该key的密码。这里有一些代码可以帮助您入门require'rubygems'require'google/api_client'
我已经创建了一个基本的身份验证key,现在我只是想使用它。我尝试了几种不同的变体,但似乎都没有在请求header中显示授权。$auth='BasiccmFtZXNoQHVzYW1hLmNvbTpyYW1lc2h1JEBtcA=='@response=resource.post('Authorization'=>$auth)nor@response=resource.post(:authorization=>$auth)nor@response=resource.post(:Authorization=>$auth)nor@response=resource.post(:content_
介绍pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:简单灵活,容易上手支持参数化能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests)pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等测试用例的skip和xfail处理可以很好的和jenkins集成
📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战
我正在关注RyanBatesScreenCast#360Facebook身份验证...当我到达点击链接登录facebook的部分时,我得到一个{"error":{"message":"Missingclient_idparameter.","type":"OAuthException","code":101}}我尝试像之前所说的那样重新启动服务器我正在拔头发试图弄清楚这一点我在facebook开发页面上的网站url是正确的我已经按照他的步骤数百次 最佳答案 可能是你没有为FACEBOOK_KEY和FACEBOOK_SECRET设置e