15年的時候,出了rails5,有個新特性actioncable.剛好公司有個關(guān)于推送的需求,但是Rails的版本是Rails4.
想使用actioncable.找了很久找到了一個可以使用的官方的gem. 16年的時候在公司項目中用了進(jìn)去. 現(xiàn)在打算把這個寫出來,因為好像很多人都不知道rails4有這個gem可以使用.
在gemfile添加
gem 'actioncable', github: 'rails/actioncable', branch: 'archive'
ps: 為了防止作者把分支刪除,可以先備份一個到自己的倉庫里.
bundle
之后需要配置一番,這個可不像rails5
那么棒,不用配置都行.application.js
...
//= require cable...
在app
文件夾下創(chuàng)建相關(guān)的目錄
channels/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :push_store
def connect
self.push_store = find_verified_user.store
end
protected
def find_verified_user
session_key = Rails.application.config.session_options[:key]
user_id = cookies.encrypted[session_key]['user_id']
if verified_user = User.find_by(id: user_id)
verified_user
else
reject_unauthorized_connection
end
end
end
end
# note: 因為websocket不支持session傳輸绪氛,所以此處需要由cookies解密
channels/orders_channel.rb
class OrdersChannel < ApplicationCable::Channel
def subscribed
stream_from "order_channel_#{push_store.id}"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
# subscribed是連接過來發(fā)生的行為套啤,unsubscribed是斷開連接發(fā)生的行為。
我們在上面將最基本的橋梁搭建好了,那么我得去創(chuàng)建一個消費(fèi)者去使用他磨确。 在 app/javascripts/
下創(chuàng)建一個 app.es6
let App = {};
App.cable = Cable.createConsumer(`/cable`);
App.messaging = App.cable.subscriptions.create('OrdersChannel', {
received: function(data) {
$(this).trigger('received', data);
}
});
消費(fèi)者創(chuàng)建好之后,我們需要播報一條消息,讓他去監(jiān)聽行為并做出處理 在 app/jobs
下創(chuàng)建 order_broadcast_job.rb
class OrderBroadcastJob < ActiveJob::Base
queue_as :default
def perform(store)
ActionCable.server.broadcast "order_channel_#{store.id}", { message: "message", user: "current_user" }
end
end
可以發(fā)現(xiàn),這個任務(wù)就是去向order_channel
播報一條通知慈俯,可以理解為:我發(fā)布了一個廣播,指定進(jìn)入到order_channel
. 連接上來拥峦,自然而然的觸發(fā)了subscribed
. 廣播指定的通道贴膘,會去匹配stream_from
.
上面我們發(fā)布了一個廣告有任務(wù)了,那么消費(fèi)者就會積極相應(yīng)略号,主動接收任務(wù)步鉴。 接收了任務(wù)之后,就會發(fā)生對應(yīng)的行為璃哟。app/javascripts/order.es6
$(function($) {
$(App.messaging).on('received', function(event, data) {
let count = 0
const message = () => {
count++;
if(count%2==1){
document.title='【你有新的消息】'
}else {
document.title='【 】'
}
}
setInterval(message, 800)
});
});
新建cable
文件夾,與app文件夾同級 cable/config.ru
require ::File.expand_path('../../config/environment', __FILE__)
Rails.application.eager_load!
require 'action_cable/process/logging'
run ActionCable.server
在bin文件夾下創(chuàng)建cable
腳本
#!/bin/bash
bundle exec puma -p 28080 cable/config.ru
本地使用的時候,直接$bin/cable
就好.