好吧,有很多关于 websockets 的信息。技术本身是惊人的,这一点毋庸置疑。在我开始在我的应用程序中使用它们之前,我只想让社区回答这些问题:
"...in order to maintain presence, the app can send keep-alive messages on the WebSocket to prevent it from being closed due to an idle timeout..."
"...ideally a future version of WebSocket will support timeout discovery, so it can either tell the application the period for keep-alive messages..."
这感觉就像似曾相识。早些时候,我们不得不每隔 %period_time% 轮询服务器一次,以获取所需的更新信息。对于 websockets,我们必须每隔 %period_time% 使用keep-alive 消息 轮询 websocket 服务器一次,以确保互联网连接仍然有效/websocket 服务器仍在工作。利润是多少?
关于这些保持事件消息的另一件事。 Websocket 协议(protocol)具有比 HTTP(S) 使用更少流量的优势。如果我们发送 keep-alive 消息,流量优势似乎消失了。或者可能不是?
如果我使用 websockets,我应该如何处理我的应用程序中的互联网丢失?我的意思是当互联网连接突然丢失时的真实情况(我的意思是没有发生“navigator.offline”事件)。我应该使用某种 setTimeout 函数来查找保持事件消息还是有更好的方法来处理这种情况?
REST 让我们清楚地了解应用程序应该如何工作以及请求应该是什么样子。在基于 websocket 的应用程序中执行此操作的最佳方法是什么?我应该只用(比如说)带有 request.action 字段的 JSON 编码消息吗?应用程序应该如何执行 PUT 请求? REST 模型中有 URL 资源来处理这个问题,所以我应该结合使用这些方法还是有更简单的方法?
最佳答案
我认为您的大部分问题都可以通过了解 WebSockets 的真正用途来澄清。 WebSockets 的主要设计目的并不是要替换任何已经存在且运行良好的东西。例如,它并非设计为 AJAX 的低开销版本。目的是在浏览器和服务器之间提供双向、低延迟、全双工的通信 channel 。它的真正目的是启用一个新的 Web 应用程序领域或改进当前滥用 HTTP 以实现双向通信的应用程序。
考虑到这一点,让我对您的要点发表评论:
周期性 WebSockets ping/pong 消息的目的有两个:防止 channel 因 TCP 超时而关闭,以及更快地检测 channel 何时关闭(这在历史上是 TCP 的弱点)。 HTTP/AJAX 轮询的目的是绕过 HTTP 不是双向的这一事实(即客户端轮询让服务器有机会发回数据)。 WebSocket ping/pong 帧通常为 2 个字节长。 HTTP/AJAX 轮询需要完整的 header 、cookie 等,每个请求/响应的总和很容易超过一千字节。即使您通过 WebSockets 每秒发送 10 次 ping/pong,您仍然不太可能与每 2 秒一次的 HTTP/AJAX 轮询的开销相比。但是,请注意,应用程序无法发送 ping/pong 消息。这是在浏览器和服务器之间。
如果您失去互联网连接,您将收到一个 onclose 事件。如果您的浏览器没有为您处理 ping/pong 消息,那么在网络连接中断后您尝试发送消息之前,您可能不会收到 onclose。
我不会用 WebSockets 替换有效的 RESTful 服务。您可能会做很多映射工作,但获益甚微(同样,WebSockets 并不是为了取代已经运行良好的东西而设计的)。我可以设想您可能同时拥有两者的情况:REST 用于状态传输,WebSockets 用于事件通知。例如。服务器发送一条 WebSocket 消息,指示“发生了一些变化”,这会触发客户端执行 REST 请求以找出变化。
更新:
澄清:您可以通过 WebSockets 实现 REST,但这在哲学上是不匹配的。 REST 是一种对底层传输系统没有意见的架构风格。它是一种受限架构:“客户端-服务器”、“无状态”、“可缓存”、“分层系统”、“按需编码”和“统一接口(interface)”。 WebSockets 不受这些限制;它是一个通用的消息传输系统。您可以将 WebSockets 限制为 RESTful,但在您深入了解 REST 和 WebSockets 并且可以确定何时这样做是正确的之前不要这样做。
关于javascript - 网络套接字。互联网丢失、保持事件消息、应用程序架构等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8758667/
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成
一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果