apache tomcat 8 websocket来源和客户端地址 [英] apache tomcat 8 websocket origin and client address
问题描述
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屋!