apache tomcat 8 websocket来源和客户端地址 [英] apache tomcat 8 websocket origin and client address

查看:42
本文介绍了apache tomcat 8 websocket来源和客户端地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

H.e.l.l.o 社区,我希望有人可以帮助我...我正在使用 apache tomcat 8.0.0-RC5 和 JSR-356 web socket API ...我有两个问题:

H.e.l.l.o community, i hope someone can help me ... i am using apache tomcat 8.0.0-RC5 and JSR-356 web socket API ... I have 2 questions:

1) 是否可以通过@OnOpen 方法获取客户端 ip ??

1) Is it possible to get the client ip on @OnOpen method ??

2) 是否有可能获得连接的来源???

2) Is it possible to get the origin of the connection ???

我遵循了tomcat发行版附带的websocket示例,但找不到答案....我的java类基本上如下

I followed the websocket example which comes with the distribution of tomcat and i was not able to find the answers .... My java class is basically as follow

@ServerEndpoint(value = "/data.socket")
public class MyWebSocket {
    @OnOpen
    public void onOpen(Session session) {
        // Here is where i need the origin and remote client address
    }

    @OnClose
    public void onClose() {
        // disconnection handling
    }

    @OnMessage
    public void onMessage(String message) {
        // message handling
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        // Error handling
    }
}

推荐答案

我知道这个问题很老,但以防万一其他人在网络搜索中找到它:

I know this question is old, but just in case someone else finds it in a web search:

是的,有一个简单的解决方法.Servlet 可以接收和转发 WebSocket 升级请求.诀窍是获取客户端 IP 地址并将其作为参数公开.

Yes there is an easy workaround. A Servlet can receive and forward a WebSocket upgrade request. The trick is to get the client IP address and expose it as a parameter.

这是您的 servlet 代码:

Here's your servlet code:

@WebServlet("/myExternalEntryPoint")
public class WebSocketServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        var dispatcher = getServletContext().getRequestDispatcher("/myInternalEntryPoint");
        var requestWrapper = new MyRequestWrapper(request);
        dispatcher.forward(requestWrapper, response);
    }
}

这里是 MyRequestWrapper:

And here's MyRequestWrapper:

class MyRequestWrapper extends HttpServletRequestWrapper {
    public RequestWrapper(HttpServletRequest request) {
        super(request);
    }

    public Map<String, String[]> getParameterMap() {
        return Collections.singletonMap("remoteAddr", new String[] {getRequest().getRemoteAddr()});
    }
}

现在在您的 WebSocket 实现中,您将能够通过 javax.websocket.Session.getRequestParameterMap() 获取 remoteAddr.

Now in your WebSocket implementation, you'll be able to get remoteAddr via javax.websocket.Session.getRequestParameterMap().

当然,如果您的原始请求具有您关心的参数,则您需要创建一个也包含这些参数的地图.此外,我建议您附加一个单独的秘密参数并在您的 WebSocket 代码中检查它,以防止任何人直接访问内部入口点.

Naturally, if your original request has parameters that you care about, you'll need to create a map that includes those as well. Also I recommend you append a separate, secret parameter and check for it in your WebSocket code to prevent anyone from hitting the internal entry point directly.

我发现这是可能的,因为 Tomcat 源代码 (WsFilter.java) 中的这个深思熟虑的注释:

I figured out this was possible because of this thoughtful comment in the Tomcat source code (WsFilter.java):

// No endpoint registered for the requested path. Let the
// application handle it (it might redirect or forward for example)

这篇关于apache tomcat 8 websocket来源和客户端地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆