我最近在学习 websocket-rails (https://github.com/websocket-rails/websocket-rails), 可以用来建立多人聊天室,但是不知道怎么建立 one to one 的聊天,类似 qq 的私人聊天,我没有找到相关的 api. 请指点下,谢谢。
socket.io 我也看了下,他有提供private message
这个 event,可以监听from
和to
.
ruby-china 的通知机制也类似,推送到个人。于是我参考了 ruby-china 的代码,发现是用的 faye-rails (https://github.com/jamesotron/faye-rails).
# https://github.com/ruby-china/ruby-china/blob/master/app/models/notification/base.rb#L20
# coding: utf-8
class Notification::Base
store_in collection: 'notifications'
field :read, default: false
belongs_to :user
index read: 1
index user_id: 1, read: 1
scope :unread, -> { where(read: false) }
after_create :realtime_push_to_client
after_update :realtime_push_to_client
def realtime_push_to_client
if self.user
hash = self.notify_hash
hash[:count] = self.user.notifications.unread.count
FayeClient.send("/notifications_count/#{self.user.temp_access_token}", hash) # 注意self.user.temp_access_token 和 FayeClient
end
end
end
# https://github.com/ruby-china/ruby-china/blob/55a3b35d9bd3db028221a4b6470a2f4e04c802dd/app/models/faye_client.rb
# faye_client.rb
require 'net/http'
class FayeClient
def self.send(channel, params)
Thread.new {
params[:token] = Setting.faye_token
message = {channel: channel, data: params}
uri = URI.parse(Setting.faye_server)
Net::HTTP.post_form(uri, message: message.to_json)
}
end
end
# user model
def temp_access_token
Rails.cache.fetch("user-#{self.id}-temp_access_token-#{Time.now.strftime("%Y%m%d")}") do
SecureRandom.hex
end
end
initNotificationSubscribe : () ->
return if not App.access_token?
faye = new Faye.Client(App.faye_client_url)
faye.subscribe "/notifications_count/#{App.access_token}", (json) ->
span = $("#user_notifications_count span")
new_title = document.title.replace(/^\(\d+\) /,'')
if json.count > 0
span.addClass("badge-error")
new_title = "(#{json.count}) #{new_title}"
url = App.fixUrlDash("#{App.root_url}#{json.content_path}")
console.log url
$.notifier.notify("",json.title,json.content,url)
else
span.removeClass("badge-error")
span.text(json.count)
document.title = new_title
true
具体来说通过 token 来区分和维护多个 channel, 即每一个用户和 server 之间酒有一个 channel, 不过 faye-rails 不是走的 websocket.
见官网Faye is a publish-subscribe messaging system based on the Bayeux protocol.
但是官方的架构有说:
# http://faye.jcoglan.com/architecture.html
Persistent connections using WebSocket
Long-polling via HTTP POST
Cross Origin Resource Sharing
Callback-polling via JSON-P
这也是我疑惑不解的地方。可能作者加了 websocket 部分的实现。
Since version 0.5, Faye has supported WebSockets as a network transport for sending messages to the browser. The code that handles this is decoupled from the rest of the library and can be used to make your own WebSocket applications.
These classes are available as a stand-alone library, faye-websocket
https://github.com/DavidEGrayson/websocket-chat/blob/master/rws1/server.rb
https://blog.engineyard.com/2013/getting-started-with-ruby-and-websockets