在 Websocket 会话中访问 UserAgent?
Posted
技术标签:
【中文标题】在 Websocket 会话中访问 UserAgent?【英文标题】:Access UserAgent in Websocket session? 【发布时间】:2015-03-09 10:19:29 【问题描述】:使用 Java 的“JSR 356 - Java API for WebSocket”的 Tyrus 参考实现,我找不到访问用于 Websocket 升级的 HTTP 连接的方法。因此,我无法访问浏览器发送的 HTTP 标头。
有没有办法读取 HTTP UserAgent 标头?
将“会话”对象转换为“TyrusSession”或类似对象是可以接受的,无论如何我都必须这样做才能获得远程地址。在 Websocket 连接中再次发送 UserAgent 作为消息将是我的后备解决方案。
【问题讨论】:
似乎是***.com/questions/28188172/…的副本 @PavelBucek:问题听起来确实相似,但答案不合适:使用 ServerEndpointConfig.Configurator,我只能访问 Websocket 握手的标头,即:connection=[Upgrade], host=[localhost:8025], origin=[localhost:8025], sec-websocket-key=[vi6GPNd4GIj2oRTcwzWKYA==], sec-websocket-version=[13], upgrade=[websocket]
request.getHttpSession( ) 仅适用于 Java EE 容器并在“正常”模式下给出 NULL。
User-Agent 标头(发送时)应该在那里 - 没有其他方法可以获取 User-Agent(Web 套接字协议不会在任何地方发送这样的信息)。
哦,确实,只是Java不发送一个。为了让这个问题至少有点用处,我将发布一个以源代码作为答案的解决方案。
【参考方案1】:
警告:ServerEndpointConfig 在所有端点实例之间共享,并且可以同时完成多个升级请求!见 cmets!
端点得到一个配置器:
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/foo", configurator = MyServerEndpointConfigurator.class)
public class MyEndpoint
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) throws Exception
String ip = ((TyrusSession) session).getRemoteAddr();
String userAgent = (String) endpointConfig.getUserProperties().get("user-agent");
...
配置器如下所示:
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
public class MyServerEndpointConfigurator extends ServerEndpointConfig.Configurator
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
if (request.getHeaders().containsKey("user-agent"))
sec.getUserProperties().put("user-agent", request.getHeaders().get("user-agent").get(0)); // lower-case!
【讨论】:
:-) 这与我最初写的答案相似,但这不是一个好的解决方案。 ServerEndpointConfig 在所有端点实例之间共享,并且可以同时完成多个升级请求 - 这将有效地重写“用户代理”条目并且端点将没有正确的信息.. 那我最好删除我的答案。但是,我在其他问题或您提到的 Tyrus 示例中找不到您的解决方案。在示例中,ServerEndpoint.Config 只为 websocket 客户端设置了一些响应头,它没有将任何信息传递给 ServerEndpoint,那么我应该怎么做呢? 这是一个很好的问题,不幸的是,我没有可接受的答案:-/您能否针对 WebSocket API 提出问题? java.net/jira/browse/WEBSOCKET_SPEC以上是关于在 Websocket 会话中访问 UserAgent?的主要内容,如果未能解决你的问题,请参考以下文章
Tornado WebSocket 与 Django ORM 与共享会话