Ruby 怎样使用 websocket 建立 one to one 的聊天
我最近在学习 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部分的实现.
也可以看看GoEasy文库的其他资料。