WebSockets – 创建渠道和推送数据的正确方法

我有一个场景,我想通知我的网站用户,有人评论了他们也评论过的文章。 这有点像当有人回答问题时SO通知我的方式!

服务器端,我坚持评论,然后查找评论同一篇文章的所有用户。 然后我播出(我正在使用Atmosphere):

PushContext pushContext = PushContextFactory.getDefault().getPushContext(); for(User u : users){ // channel name, message pushContext.push("/user_" + u.id, "someone commented! blah blah"); } 

我正在广播的“频道”是用户的“自己的”频道,因为我不希望每个用户都收到通知。 我在频道名称中使用用户ID来实现此目的。

这是确保只有相关用户得到通知的正确方法吗?

我想我还想再做两件事:

  1. 只推送我认为仍然在线的用户。 如果他们不在线,则浪费资源推动他们。
  2. 加密邮件,因为否则任何人都可以收听我的邮件,如果他们知道我的用户ID。

还有什么我需要考虑的吗?

SO使用WebSockets,例如,当对此post发表评论时,您会在SO页面左上角的状态栏中收到通知。

加载页面后,浏览器会发出协议升级请求,如下所示:

 Request URL:ws://sockets-se.or.stackexchange.com/ Request Method:GET Status Code:101 Switching Protocols Request Headersview source Connection:Upgrade Cookie:__qca=P0-1697817643-1763440830313; __utma=27376923.959753990.1338240830.1353943751.1384115154.33; __utmc=27693525; __utmz=27699983.1356175156.31.31.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided) Host:sockets-se.or.stackexchange.com Origin:http://stackoverflow.com Sec-WebSocket-Extensions:x-webkit-deflate-frame Sec-WebSocket-Key:6qFl45+6gZ526yMMo79zWQ== Sec-WebSocket-Version:13 Upgrade:websocket (Key3):00:00:00:00:00:00:00:00 Response Headersview source Connection:Upgrade Sec-WebSocket-Accept:B4h2G+gi78iNZZXg+o6iAztgF1I= Upgrade:websocket (Challenge Response):00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 

然后打开套接字,服务器可以向浏览器发送更新。 例如,浏览器收到我的评论通知,如下所示:

 {"action":"1-question-12993099","data":"{\"a\":\"comment-add\",\"id\":12993099,\"commentid\":19334206,\"acctid\":1298157}"} 

它不包含实际评论; 它似乎只是用来告诉浏览器显示红色图标。 当您单击时,它会发出获取页面的请求,包括注释。 问题ID(12993099),评论ID(19334206)和帐户ID(1298157)包含在该框架中。

我在上面看不到任何可以阻止某些黑客创建一个Web套接字来监听你的通知的内容。 我认为Cookie是我的Google Analytics(分析)Cookie,或者至少是第二个和第三个Cookie。 也许第一个是你不会知道的一些代码,如果我不是刚刚发布它(不用担心,我改变它!)。

在你的Atmosphere示例中,我知道当Web套接字不起作用时,它默认为长轮询,然后请求其中包含通道名称的URL。 因此,您可以让客户端生成一个只知道它的通道名称,并将其与登录用户相关联。 但是任何嗅探网络的人都会再次访问您的流量,因此您必须使用安全Web套接字(WSS)和HTTPS(用于长轮询后备)来保护它。