1

我有一个场景,我想通知我网站的用户有人评论了他们也评论过的文章。这很像当有人回答问题时 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。

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

4

1 回答 1

1

SO 使用 WebSockets,例如,当对此帖子发表评论时,您会在 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,或者至少是第二个和第三个。也许第一个是一些你不会知道的代码,如果我不只是发布它(不用担心,我会改变它!)。

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

于 2012-12-22T17:20:12.530 回答