Ruby 怎样使用 websocket 建立 one to one 的聊天

Ruby 怎样使用 websocket 建立 one to one 的聊天

我最近在学习 websocket-rails (https://github.com/websocket-rails/websocket-rails), 可以用来建立多人聊天室,但是不知道怎么建立one to one的聊天,类似qq的私人聊天, 我没有找到相关的api. 请指点下,谢谢.


socket.io我也看了下,他有提供private message这个event,可以监听fromto.


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文库的其他资料。

发表评论

邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据