17

在我的应用程序中,我想通知用户何时在评论或帖子中提及他/她。
用户手柄是@user_name,类似于Facebook
对于提到的数据库表如下所示:在Rails中实现通知

Mention 
    mentioned_by: user_id (foreign key) 
    user_mentioned: user_id (foreign key) 
    comment_id: (foreign key) 
    post_id: (foreign key) 

我不能想出一个办法,虽然实现它。 Facebook/Twitter如何做到这一点?

我决定使用的是使用ActiveRecord callbacks/ Observer design pattern,并且每当将新的评论/帖子保存到数据库时,我可以浏览帖子/评论的内容,并查看任何提及,然后执行通知需要。

我觉得有一些缺失的部分,我没有得到它的权利。
这是做这件事的最好方法吗?

+0

我鼓励你在这个问题上添加“facebook”和“twitter”标签,这样其他人可能会更容易碰到它。此外,也许开始对此的赏金?我相信很多人都对这个问题的答案感兴趣。 – dmonopoly

+0

@daze:谢谢你的建议。添加正确的标签确实有帮助。 :) –

回答

27

Facebook和Twitter不是中等大小的Rails应用程序。他们是公司。运行它们的技术是分布式的,主要是定制的,特别是在Facebook的情况下。

您似乎在抓的部分是他们如何确定以高性能和可扩展的方式通知的人。这是狗屎变得真实的地方。你可以找到很多有关它们背后的架构的信息,当然有很多很棒的东西可以帮助你思考这些事情,但最终没有一个东西会成为你实现任何应用程序的东西,重新建设。

http://www.quora.com/What-is-Facebooks-architecture

Facebook Architecture

http://www.infoq.com/news/2009/06/Twitter-Architecture

http://engineering.twitter.com/2010/10/twitters-new-search-architecture.html

了大量在Quora的更多有趣的细节。


不幸的是,这些都没有让你更接近你的目标。我认为你最初做的最现实的事情就是简单地配合Pusher这样的服务向客户端发送消息而不用担心,使用ActiveRecord Observer将通知添加到工作人员实际发送这些通知的background queue推动者。这是一天或更少的工作,它应该很好地扩展到每天至少10k个通知。一旦你开始出现性能问题,将Observer和Pusher放在Goliath之类的东西上,它可以在本地处理这两种工作。

底线,学什么你可以对已经通过的步伐投入大,经验丰富的系统,但主要只是为了看看问题他们遇到了和他们是如何解决他们。这些方法在大家伙中并不一样,而且每种实现都会有所不同。

希望这有助于指引你朝好的方向发展。 :)

+0

谢谢你指点我正确的方向。 –

2

您可以在保存记录时使用ActiveRecord回调(如before_save,after_save或before_create,after_create)来查看评论内容,找到并创建所有提及模型并将其保存到db。

+0

我在上面的问题中提到过。我所问的是,如果这是最好的方式。 Facebook/Twitter如何做到这一点。 –

2

Tumblr使用我认为可以处理音量的Redis排队系统(如Resque)。

做一个回调(如你所说)并把它交给Resque。 (有一个Railscasts about Resuqe recently

+0

感谢您的回答。但实际上,我更感兴趣的是了解实现这一目标的最佳方式,而不是在排队soln上进行优化。不过,非常感谢您的建议。我会记住这一点。 –

1

有没有单一的推荐方法。在超级关卡中,您可能需要查看'Comet programming',Polling和WebSockets [HTML5],然后选择正确的组合。有几个很棒的实现来管理rails中的推送通知。 Orbited,Juggernaut,PusherApp,Faye等。你必须深入挖掘哪些使用网络套接字&,并回退到flash选项来处理完全支持。

Faye也提供了Node.js配置,但我不确定其他人。

姑且步骤将类似于:

  1. 保存的内容 - 排队它解析器
  2. 解析文档内容以找出涉及用户 - 使用引入nokogiri或同等学历。
  3. 彗星/如果您正在查看Twitter之类的方法,请将其作为一个单独的流程轮询给current_session中的相关用户。
  4. //对邮政记录做其他事情
  5. 将通知推送给相关用户,并在稍后联机时将其销毁()。

    希望能给出一些方向。

1

我知道这个问题已经过时了,但我最近发布了一个MentionSystem gem到rubygems.org,它允许在提及者对象和提及者之间创建提及,它还允许您检测facebook/twitter styler中的提及,例如@ username1和#hashtag为了创建提及。

宝石托管在GitHub上:https://github.com/pmviva/mention_system

比方说你有一个帖子,可以提及用户@username的形式。

你有类

class Post < ActiveRecord::Base 
    act_as_mentioner 
end 

class User < ActiveRecord::Base 
    act_as_mentionee 
end 

然后定义一个定制的提处理器:

class PostMentionProcessor < MentionSystem::MentionProcessor 
    def extract_mentioner_content(post) 
    return post.content 
    end 

    def find_mentionees_by_handles(*handles) 
    User.where(username: handles) 
    end 
end 

然后在您的帖子控制器创建操作你必须:

def create 
    @post = Post.new(params[:post]) 
    if @post.save 
    m = PostMentionProcessor.new 
    m.add_after_callback Proc.new { |post, user| UserMailer.notify_mention(post, user) } 
    m.process_mentions(post) 
    end 

    respond_with @post 
end 

如果您的文章在其内容中包含@ user1,@ user2和@ user3,提及处理器将解析user1,user2和user3,将找到具有用户名[user1,user2,user3]的用户,然后在数据库中创建提及,在每一次提及之后,它将运行后面的回调,在该示例中将发送通知邮件和用户之间的提及的电子邮件。