【问题标题】:How to access client hostname, http headers etc from a Java websocket server?如何从 Java websocket 服务器访问客户端主机名、http 标头等?
【发布时间】:2015-03-27 02:41:25
【问题描述】:

我已经学习了许多教程和示例代码,但我还没有看到一种访问客户端 HTTP 标头、主机名等的方法,就像我们在 Servlet 的请求对象中那样。

我该怎么做?

假设我将 onOpen 定义为 -

@OnOpen
    public void onOpen(Session session) {

} 

在上述方法中,有没有一种方法可以使用会话字段访问底层 HTTP 连接详细信息?即使我可以访问底层 Servlet(如果有的话)我也很好

【问题讨论】:

标签: java http servlets websocket


【解决方案1】:

参见第 4.1.1.5 章Tyrus user guide。从 ServerEnpointConfig.Configurator 获取信息到端点实例需要做一些工作,但可以完成。 (见ModifyRequestResponseHeadersTest.java

【讨论】:

  • 想详细说明一下?这里给出的答案:stackoverflow.com/questions/28939581/… 似乎是基于你在这个答案中所说的。但是,您随后在此处评论说,由于并发性,这样做不安全。那么,听起来真的不能安全地完成吗?我们是否应该将从 modifyHandshake 方法读取的标头存储到 ThreadLocal 中,并希望执行握手的同一线程将调用 onopen 回调?还有什么?
【解决方案2】:

基于link1link2

我终于想通了,我们可以用下面两个类来获取客户端IP,其实你可以用暴露的httpservletRequest做更多的事情...

ServletAwareConfigurator .java

package examples;
import java.lang.reflect.Field;

import javax.servlet.http.HttpServletRequest;

import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;

public class ServletAwareConfigurator extends ServerEndpointConfig.Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
        HttpServletRequest httpservletRequest = getField(request, HttpServletRequest.class);
        String sClientIP = httpservletRequest.getRemoteAddr();
        config.getUserProperties().put("clientip", sClientIP);
        // ...
    }

    //hacking reflector to expose fields...
    private static < I, F > F getField(I instance, Class < F > fieldType) {
        try {
            for (Class < ? > type = instance.getClass(); type != Object.class; type = type.getSuperclass()) {
                for (Field field: type.getDeclaredFields()) {
                    if (fieldType.isAssignableFrom(field.getType())) {
                        field.setAccessible(true);
                        return (F) field.get(instance);
                    }
                }
            }
        } catch (Exception e) {
            // Handle?
        }
        return null;
    }
}

GetHttpSessionSocket.java

package examples;
import java.io.IOException;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/example",
    configurator = ServletAwareConfigurator.class)
public class GetHttpSessionSocket {
    private Session wsSession;
    private String sClientIP;

    @OnOpen
    public void open(Session session, EndpointConfig config) {
        this.wsSession = session;
        this.sClientIP = (String) config.getUserProperties()
            .get("clientip");
    }
    @OnMessage
    public void echo(String msg) throws IOException {
        wsSession.getBasicRemote().sendText(msg);
    }
}

【讨论】:

    猜你喜欢
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2018-05-21
    • 2019-10-26
    • 1970-01-01
    • 2013-02-02
    • 2018-05-15
    相关资源
    最近更新 更多