开源项目 ruby-china 代码研究

xwf286 · 2013年05月21日 · 最后由 zhangyue649800924 回复于 2014年03月16日 · 5183 次阅读

内容比较丑陋,算是个抛砖引玉吧,如果不是新手,就走开吧。 最近发现 rc 的源代码的资料比较高,网上搜了一遍,也没有发现类似面向新手的分析性文章。

redis 使用 计数器

topicController
    @topic.hits.incr(1)
Topic
    include Redis::Objects
    counter :hits, :default => 0
end

消息系统: 采用 faye: 参考资料: http://railscasts.com/episodes/260-messaging-with-faye?view=asciicast

当用户 A 回复用户 B 的评论时,rc 会使用消息系统将该回复通知到用户 B: 1 当 create 一个新的 Reply 时,会调用 Reply 的回调方法:after_create

class Reply
  after_create do
    Reply.delay.send_topic_reply_notification(self.id)
  end

2 创建 Notification::TopicReply

def self.send_topic_reply_notification(reply_id)
    reply = Reply.find_by_id(reply_id)
    return if reply.blank?
    topic = reply.topic
    return if topic.blank?
    # 给发帖人发回帖通知
    if reply.user_id != topic.user_id && !reply.mentioned_user_ids.include?(topic.user_id)
      Notification::TopicReply.create :user_id => topic.user_id, :reply_id => reply.id
      reply.notified_user_ids << topic.user_id
    end

    # 给关注者发通知
    topic.follower_ids.each do |uid|
      # 排除同一个回复过程中已经提醒过的人
      next if reply.notified_user_ids.include?(uid)
      # 排除回帖人
      next if uid == reply.user_id
      Notification::TopicReply.create :user_id => uid, :reply_id => reply.id
    end
    true
  end

3 Notification::TopicReply 的基类是 Notification::Base

class Notification::TopicReply < Notification::Base
  belongs_to :reply

  delegate :body, :to => :reply, :prefix => true, :allow_nil => true

  def notify_hash
    return "" if self.reply.blank?
    { 
      :title => "关注的话题有了新回复:", 
      :content => self.reply_body[0,30],
      :content_path => self.content_path
    } 
  end

  def content_path
    return "" if self.reply.blank?
    url_helpers.topic_path(self.reply.topic_id)
  end
end

4Notification::Base 的 create 方法有个回调:realtime_push_to_client,在该回调里会将通知广播出去 Notification::Base

after_create :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)
    end
  end

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

5 客户端接受到上面的通知后:

initNotificationSubscribe : () ->
  faye = new Faye.Client(FAYE_SERVER_URL)
  notification_subscription = faye.subscribe "/notifications_count/#{CURRENT_USER_ACCESS_TOKEN}",(json) ->
    span = $("#user_notifications_count span")
    new_title = $(document).attr("title").replace(/\(\d+\) /,'')
    if json.count > 0
      span.addClass("badge-error")
      new_title = "(#{json.count}) #{new_title}"
      url = App.fixUrlDash("#{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).attr("title", new_title)
  true 

内容还行

整理一下代码格式就更好了😄

楼主用 markdown 整理一下代码,这篇文章就会很受欢迎。

正好最近在用 faye 期待楼主整理代码格式

果然是好东西!!mark shopify 也在用这个东西

再试试这个功能

没有反应

不知道咋用

不清楚

faye 测试

chrome 没有反应

新手,学习了,感谢楼主。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号