WebSocket

WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

背景:

现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

优点:

  • 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小
  • 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少
  • 保持连接状态。于HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。

https://zh.wikipedia.org/wiki/WebSocket


Action Cable

1. a thick strong metal rope used on ships, to support bridges etc

通过提供Client Javascript框架和Server端Ruby框架把 WebSocket协议和Rails应用集成起来。

2. Publish-Subscribe功能

指定好发布者和订阅者,之后发布者自动发送新数据给订阅者。比传统方式高效。

3 Server-Side Components

3.1 Connections 第一步连接设置。

Connections are instances of ApplicationCable::Connection.对连接的授权就是在这个类中完成的,对能够识别的用户会建立 consumer-connection pair.

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    # 声明连接标志索引,用于之后查找指定连接
    identified_by :current_user
 
    def connect
      # 尝试连接,把cookie发送给连接实例self。
      # 设置current_user,之后就能检索指定用户打开的所有连接。
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable', current_user.name
    end
 
    protected
      def find_verified_user
        if verified_user = User.find_by(id: cookies.signed[:user_id])
          verified_user
        else
          #模块自带方法, 如果找不到,就关闭连接,返回404提示,就是下面2句话。
          # logger.error "An unauthorized connection attempt was rejected"
          # raise UnauthorizedError
          reject_unauthorized_connection
        end
      end
  end
end

identified_by(*identifiers)中的核心语法是:attr_accessor identifier, 就是建立一个存取宏, 产生一个实例名字和存取它的方法。然后把它放入这个数组集合中。

def identified_by(*identifiers)
Array(identifiers).each { |identifier| attr_accessor identifier }
self.identifiers += identifiers
end
 

3.2 Channels

类似controller做的标准MVC步骤。

http://api.rubyonrails.org/classes/ActionCable/Channel/Base.html (api)

Rails creates ApplicationCable::Channel class 封装共享的逻辑在你的各channels.

3.21 Parent Channel Setup

你自己创建自己的channel类,继承它。 命令:rails generate channel products。

pasting

在类中定义订阅subscribed

 

,取消订阅,拒绝订阅reject(资质审核)等10多个方法。

# app/channels/chat_channel.rb

class ChatChannel < ApplicationCable::Channel # 当用户成为此频道的订阅者时调用
  def subscribed

end

end

4 Client-Side Components

4.1 Connections

Consumers require an instance of the connection on their side. This can be established using the folling JavaScript, which is generated by default by Rails :

4.11 Connect Consumer

identical  app/assets/javascripts/cable.js

// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
//
//= require action_cable
//= require_self
//= require_tree ./channels
 
(function() {
  this.App || (this.App = {});
 
  App.cable = ActionCable.createConsumer();
 
}).call(this);

4.12 Subscriber

A consumer becomes a subscriber by creating a subscription to a given channel:

create  app/assets/javascripts/channels/products.coffee

App.products = App.cable.subscriptions.create "ProductsChannel",
  connected: ->
    # Called when the subscription is ready for use on the server
  disconnected: ->
    # Called when the subscription has been terminated by the server
  received: (data) ->
    # Called when there's incoming data on the websocket for this channel
 

5. Client-Server Interactions 交互

 

create  app/channels/products_channel.rb

5.1 Streams

Streams provide the mechanism by which channels route published content (broadcasts) to their subscribers.

如果和模型关联的流,用stream_for
class CommentsChannel < ApplicationCable::Channel       
  def subscribed 
    post = Post.find(params[:id]) 
stream_for post 

end

end

向评论频道发送广播的方式如下:

CommentsChannel.broadcast_to(@post, @comment)

发生命名的广播用stream_from ,见api

流的方法:

5.2 Broadcasting

A broadcasting is a pub/sub link

CommentsChannel.broadcast_to(@post, @comment)

5.3 Subscriptions

This Connection is called a subscription. Incoming messages are then routed to these channel subscriptions based on an identifier sent by the cable consumer.

5.4 Passing Parameters to Channels

You can pass para from the client side to the server side when creating a subscriptin. For example:

 def subscribed
    stream_from "chat_#{params[:room]}"
  end

5.5 Rebroadcasting a Message

A common use case is to rebroadcast a message sent by one client to any other connected clients.

   def receive(data)
   ActionCable.server.broadcast("chat_#{params[:room]}", data)
  end

The rebroadcast will be received by all connected clients, including the client that sent the message. Note that params are the same as they were when you subscribed to the channel.


一个基础功能演示的案例(不包含connection.rb)

https://www.cnblogs.com/chentianwei/p/9296887.html

使用broadcast功能渲染首页部分页面:

3步骤:第一建立频道,第二发送这个频道的信息,第三选择接收信息的位置。

⚠️本案例没有涉及到用户对平淡的订阅和连接。即在assets/channels/XXX_channel.rb 中设置连接。


 https://github.com/rails/actioncable-examples

完全的案例:

需要按照redis数据库。简介:Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。菜鸟教程(redis)

  下载的进程截图:

 
==> Downloading https://homebrew.bintray.com/bottles/redis-4.0.9.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring redis-4.0.9.sierra.bottle.tar.gz
==> Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==> Summary

4-2 什么是WebSocket; Action Cable的使用。Rails guide-6.3视频教学,没有看!的更多相关文章

  1. 实时更新数据,无需刷新:a,如何使用Turbolinks clearCache(), b Action Cable

    视频: https://gorails.com/episodes/how-to-use-turbolinks-clearCache?autoplay=1 用途: 更方便的实时从服务器更新局部网页,在这 ...

  2. 使用WebSocket实现服务端和客户端的通信

    开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...

  3. 刨根问底 HTTP 和 WebSocket 协议(上)

    HTTP vs WebSocket 那天和boss聊天,不经意间提到了Meteor,然后聊到了WebSocket,然后就有了以下对话,不得不说,看问题的方式不同,看到的东西也会大不相同. A:Mete ...

  4. websocket可以做什么

    本篇介绍的是websocket,但是并不介绍它的协议格式,一般能看明白http头也能明白websocket在协议切换前的协商,能看明白IP报头也就对websocket在协议切换后通讯格式不陌生.web ...

  5. Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!

    随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如 ...

  6. Web APi之控制器选择Action方法过程(九)

    前言 前面我们叙述了关于控制器创建的详细过程,在前面完成了对控制器的激活之后,就是根据控制器信息来查找匹配的Action方法,这就是本节要讲的内容.当请求过来时首先经过宿主处理管道然后进入Web AP ...

  7. 借助node实战WebSocket

    一.WebSocket概述 WebSocket协议,是建立在TCP协议上的,而非HTTP协议. 如下: ws://127.0.0.1或wss://127.0.0.1就是WebSocket请求. 注:w ...

  8. Struts2 源码分析——Action代理类的工作

    章节简言 上一章笔者讲到关于如何加载配置文件里面的package元素节点信息.相信读者到这里心里面对struts2在启动的时候加载相关的信息有了一定的了解和认识.而本章将讲到关于struts2启动成功 ...

  9. Struts2 源码分析——调结者(Dispatcher)之执行action

    章节简言 上一章笔者写关于Dispatcher类如何处理接受来的request请求.当然读者们也知道他并非正真的执行action操作.他只是在执行action操作之前的准备工作.那么谁才是正真的执行a ...

随机推荐

  1. Linux中顿号

    ``的作用是运行``之间的命令,并且将命令运行的结果返回.一般shell脚本应该是这样:result=`ls -l` (用你的命令替换ls -l,这里只是举例)这样,result就有``里面的运行结果 ...

  2. pycharm 设置文件编码的位置:Editor-->File Encodings

    打开设置-->Editor-->File Encodings 

  3. tomcat和jetty区别

    参见:https://www.cnblogs.com/fengli9998/p/7247559.html 1. Jetty更轻量级.这是相对Tomcat而言的. 由于Tomcat除了遵循Java Se ...

  4. thinkphp标签实现bootsrtap轮播carousel实例

    thinkphp标签实现bootsrtap轮播carousel实例由于轮播carousel第一个div需要设置active样式才能正常显示,上面的圆点也同样需要数字,使用volist标签在循环的同时可 ...

  5. python如何序列化json数据

    使用json模块提供的loads方法和dumps方法,可以很方便的载入和读取json数据格式.而在具体实际应用中,我们使用python数据格式是 string.list 或dict等,这类格式如何直接 ...

  6. MySQL数据库----表与表之间的关系

    表1 foreign key 表2 则表1的多条记录对应表2的一条记录,即多对一 利用foreign key的原理我们可以制作两张表的多对多,一对一关系 多对多: 表1的多条记录可以对应表2的一条记录 ...

  7. Window系统远程连接Linux服务器(非桌面系统)

    Window系统远程连接Linux服务器(非桌面系统) Window系统远程连接Linux服务器(非桌面系统),步骤: 第一步:下载Xshell远程登录软件:第二步:设置Linux服务器的IP.端口. ...

  8. Python网络爬虫案例(二)——爬取招聘信息网站

    利用Python,爬取 51job 上面有关于 IT行业 的招聘信息 版权声明:未经博主授权,内容严禁分享转载 案例代码: # __author : "J" # date : 20 ...

  9. 20145324王嘉澜《网络对抗技术》MSF基础应用

    实践目标 •掌握metasploit的基本应用方式 •掌握常用的三种攻击方式的思路. 实验要求 •一个主动攻击,如ms08_067 •一个针对浏览器的攻击,如ms11_050 •一个针对客户端的攻击, ...

  10. codevs 1423 骑士 - Tarjan - 动态规划

    题目描述 Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵 ...