4-2 什么是WebSocket; Action Cable的使用。Rails guide-6.3视频教学,没有看!
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.
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
4.12 Subscriber
A consumer becomes a subscriber by creating a subscription to a given channel:
create app/assets/javascripts/channels/products.coffee
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)
启动:
$ redis-server
查看是否启动 redis-cli ,这个命令打开终端。ping一下,pong就是成功安装了。
一个gem 'puma'一直安装不上,提示❌?怎么办?
后来查了很多资料,得到提示安装更高级的版本。
成功了,但是却要求低版本配置。
然后直接在gemfile.lock文件中找到puma修改版本到3.10.然后bundle install成功。
《Rails5敏捷开发》第406页,24.3:
bundle install以Gemfile.lock为准,安装指定的gem版本。哈哈哈哈哈。!!我竟然一直忽略了。
看guide上的聊天窗口案例:fork下来后,看不懂:
- coffee.script不是很懂。javescript也会。
- 明天再试试,已经看了一半了。对比着中文guide看。
缺陷:不懂coffee.scripte.jiavascripte语法。
对数据库的部署也不熟悉,看案例的很困难,这个action cable比较难。设计多个模块。
6 案例
7 configuration
rails guide的没有更新,需要配合git上的相同内容。
包括3个required configurations:
- a subscription adapter
- allowed request origins
- the cabel server URL(在client side 可选择的设置)
7.1 Subscription Adapter
什么是adapter?(9 Dependencies)
Action Cable提供了一个订阅adapter interface来处理它的内部发布和订阅。默认是async adapter(可用于开发和测试)。
adapter可以使用: Async, Redis, PostgreSQL adapter
默认ActionCable 会寻找配置文件config/cable.yml。这个文件必须指定an adapter为每个Rails环境。
development: adapter: redis url: redis://localhost:6379/1 test: adapter: async production: adapter: redis url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> #指向Redis server channel_prefix: Wechat_production #用于避免频道名字重复,当使用相同的饿Redis server为多个applications时。
Allowed Request Origins
Action Cable将只接受那些指定源头specific origins的请求 。
具体见ActionCable的部署: https://www.cnblogs.com/chentianwei/p/9900012.html
Consumer Configuration
具体见ActionCable的部署: https://www.cnblogs.com/chentianwei/p/9900012.html
https://github.com/rails/rails/tree/master/actioncable