WebSocket是一種在單個TCP鏈接上進行全雙工通信的協議。WebSocket通訊協議於2011年被IETF定爲標準RFC 6455,並由RFC7936補充規範。WebSocket API也被W3C定爲標準。javascript
WebSocket使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。html
背景:java
如今,不少網站爲了實現推送技術,所用的技術都是輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。git
在這種狀況下,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。github
優勢:web
https://zh.wikipedia.org/wiki/WebSocketredis
Action Cable數據庫
1. a thick strong metal rope used on ships, to support bridges etcapi
經過提供Client Javascript框架和Server端Ruby框架把 WebSocket協議和Rails應用集成起來。數組
2. Publish-Subscribe功能
指定好發佈者和訂閱者,以後發佈者自動發送新數據給訂閱者。比傳統方式高效。
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.scripte.jiavascripte語法。
對數據庫的部署也不熟悉,看案例的很困難,這個action cable比較難。設計多個模塊。
rails guide的沒有更新,須要配合git上的相同內容。
包括3個required configurations:
什麼是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時。
Action Cable將只接受那些指定源頭specific origins的請求 。
具體見ActionCable的部署: https://www.cnblogs.com/chentianwei/p/9900012.html
具體見ActionCable的部署: https://www.cnblogs.com/chentianwei/p/9900012.html
https://github.com/rails/rails/tree/master/actioncable