我有一个场景,我想通知我网站的用户有人评论了他们也评论过的文章。这很像有人回答问题时 SO 通知我的方式!
服务器端,我保留评论,然后查找对同一篇文章发表评论的所有用户。然后我广播(我使用的是 Atmosphere):
PushContext pushContext = PushContextFactory.getDefault().getPushContext();
for(User u : users){
// channel name, message
pushContext.push("/user_" + u.id, "someone commented! blah blah");
}
我正在广播的“ channel ”是用户的“自己的” channel ,因为我不希望每个用户都收到通知。我在 channel 名称中使用用户 ID 来实现此目的。
这是确保只有相关用户收到通知的正确方法吗?
我想我还想做两件事:
- 仅向我认为仍在线的用户推送。如果他们不在线,那么向他们推送资源就是浪费。
- 对消息进行加密,否则任何人只要知道我的用户 ID,就可以监听我的消息。
还有什么我需要考虑的吗?
最佳答案
SO 使用 WebSockets,例如,当对此帖子发表评论时,您会在 SO 页面左上角的状态栏中收到一条通知。
加载页面时,浏览器会发出协议(protocol)升级请求,如下所示:
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)。
我看不到上面的任何内容可以阻止某些黑客创建网络套接字来监听您的通知。在我看来,这些 cookie 就是 Google Analytics cookie,或者至少第二个和第三个 cookie 是这样。也许第一个是一些你不会知道的代码,如果我没有刚刚发布它的话(不用担心,我会更改它!)。
在您的 Atmosphere 示例中,我知道当 Web Sockets 不起作用时,它默认为长轮询,然后请求包含 channel 名称的 URL。因此,您可以让客户端生成一个只有它自己知道的 channel 名称,并将其与登录用户关联起来。但是任何嗅探网络的人都可以再次访问您的流量,因此您必须使用安全网络套接字 (WSS) 和 HTTPS(用于长轮询回退)来保护它。
关于java - WebSockets - 创建 channel 和推送数据的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12993099/