将对象从程序化Undertow JSR-356 Servlet部署传递到ServerEndpoint实例?

时间:2019-06-08 03:20:53

标签: java servlets java-websocket undertow jsr356

我正在尝试使用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的情况下将任意对象从部署端传递到实例本身。

0 个答案:

没有答案