开源项目 ruby-china 代码研究

xwf286 · May 21, 2013 · Last by zhangyue649800924 replied at March 16, 2014 · 5183 hits

内容比较丑陋,算是个抛砖引玉吧,如果不是新手,就走开吧。 最近发现 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 没有反应

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

You need to Sign in before reply, if you don't have an account, please Sign up first.