我正在尝试使用JBoss Undertow以编程方式创建WebSocket(JSR-356)servlet,并能够将创建Undertow服务器/部署的方法中的依赖项(例如下面的“ myObject”)传递到ServerEndpoint实例中后来创建的。
由于实例创建是由Undertow管理的,所以我不能仅仅将依赖项传递给构造函数。我一直在尝试使用ServerContext属性,因为它似乎可能在两端都暴露出来,但是在ServerEndpoint端访问它而没有求助于反射时会遇到问题。
部署代码:
UUID myObject = UUID.randomUUID()
Xnio xnio = Xnio.getInstance("nio", Undertow.class.getClassLoader());
XnioWorker xnioWorker = xnio.createWorker(OptionMap.builder()
.set(Options.WORKER_IO_THREADS, 1)
.set(Options.WORKER_TASK_CORE_THREADS, 3)
.set(Options.WORKER_TASK_MAX_THREADS, 5)
.set(Options.TCP_NODELAY, true)
.getMap());
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo().addEndpoint(WSMicroServer.class);
DeploymentInfo websocketDeployment = Servlets.deployment().setDeploymentName("DSA-Agent-WebSocket")
.setClassLoader(WSInterface.class.getClassLoader())
.setContextPath(contextPath)
.addServletContextAttribute("myObject", myObject)
.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, webSocketDeploymentInfo);
DeploymentManager manager = Servlets.defaultContainer().addDeployment(websocketDeployment);
manager.deploy();
Undertow server = Undertow.builder()
.setHandler(Handlers.path().addPrefixPath(websocketDeployment.getContextPath(), manager.start()))
.addHttpListener(port, bindHost)
.setWorker(xnioWorker)
.build();
server.start();
服务器端点代码:
@ServerEndpoint(value = "/", configurator = WSMicroServer.ServletAwareConfig.class)
public class WSMicroServer
{
private UUID myObject = null;
@OnMessage
public void message(Session session, String message) throws IOException
{
System.out.println(myObject + " >>> " + message);
}
public static class ServletAwareConfig extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response)
{
HttpSession httpSession = (HttpSession)request.getHttpSession(); // does not work in WildFly
config.getUserProperties().put("httpSession", httpSession);
//ExchangeHandshakeRequest req = (ExchangeHandshakeRequest)request;
//ServletWebSocketHttpExchange ex = req.exchange;
//HttpServletRequestImpl reqImpl = ex.request;
//ServletContext ctx = reqImpl.getServletContext();
//Object myObj = ctx.getAttribute("myObject");
// How can myObject be set ??
}
}
}
有很多消息来源说,您可以通过在 ServerEndpointConfig.Configurator 内调用 HandshakeRequest.getHttpSession 来轻松获得它,例如:https://stackoverflow.com/a/23405830/1060650 < / p>
但是,这在Undertow中根本不起作用。该对象始终为null。
尽管最终,我只是希望能够在不使用静态方法hack的情况下将任意对象从部署端传递到实例本身。