首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用标准JSR356 WebSocket客户端的连接超时

使用标准JSR356 WebSocket客户端的连接超时
EN

Stack Overflow用户
提问于 2015-02-16 13:53:43
回答 3查看 3.9K关注 0票数 5

我有一个连接到远程websocket服务器的Java应用程序。作为客户端,我使用的是标准的Java JSR356 WebSocket API

代码语言:javascript
复制
javax.websocket.WebSocketContainer.connectToServer(...)

但是,我还没有找到使用这个API指定连接超时的方法。当我调用connectToServer(.)方法时,它一直阻塞直到建立连接(这可能永远不会发生)。

是否有一种方法可以使用标准API指定连接超时?如果没有,有什么解决办法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-17 08:35:04

不幸的是,JSR356-JavaAPI WebSocket没有公开这一点。您将需要使用实现特性,如超时 in 泰勒斯 (参考实现)。其他实现很可能有类似的东西。

等级库中似乎还没有这方面的票据,所以如果您愿意,可以添加一个(我只能找到提到SSL属性的问题-- 规格-210)。

票数 3
EN

Stack Overflow用户

发布于 2020-06-12 18:03:49

您可以简单地在connectToServer中重写WsWebSocketContainer方法

代码语言:javascript
复制
public class WsWebSocketContainer2 extends WsWebSocketContainer {

    @Override
    public Session connectToServer(Object pojo, URI path) throws DeploymentException {
        ClientEndpoint annotation = pojo.getClass().getAnnotation(ClientEndpoint.class);
        if (annotation == null) {
            throw new DeploymentException("wsWebSocketContainer.missingAnnotation");
        }

        Endpoint ep = new PojoEndpointClient(pojo, Arrays.asList(annotation.decoders()));

        Class<? extends ClientEndpointConfig.Configurator> configuratorClazz = annotation.configurator();

        ClientEndpointConfig.Configurator configurator = null;
        if (!ClientEndpointConfig.Configurator.class.equals(configuratorClazz)) {
            try {
                configurator = configuratorClazz.getConstructor().newInstance();
            } catch (ReflectiveOperationException e) {
                throw new DeploymentException("wsWebSocketContainer.defaultConfiguratorFail", e);
            }
        }

        ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create();
        // Avoid NPE when using RI API JAR - see BZ 56343
        if (configurator != null) {
            builder.configurator(configurator);
        }
        ClientEndpointConfig config = builder.decoders(Arrays.asList(annotation.decoders())).encoders(Arrays.asList(annotation.encoders()))
                .preferredSubprotocols(Arrays.asList(annotation.subprotocols())).build();
        Map<String, Object> userProperties = config.getUserProperties();
        userProperties.put(Constants.IO_TIMEOUT_MS_PROPERTY, 999999);
        return connectToServer(ep, config, path);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-11-22 08:25:21

这件事我自己就搞定了。如果通过未来构造调用connectToServer,则可以在get()方法中使用超时。

您需要一个ThreadPool:

代码语言:javascript
复制
private final ExecutorService pool = Executors.newFixedThreadPool(10);

以下是功能:

代码语言:javascript
复制
private Future<Session> asyncConnectToServer(Object annotatedEndpointInstance, URI uri) {
        return pool.submit(new Callable<Session>() {
            @Override
            public Session call() throws Exception {
                try {
                    WebSocketContainer container = ContainerProvider.getWebSocketContainer();
                    return(container.connectToServer(annotatedEndpointInstance, uri));
                } catch (DeploymentException | IOException | IllegalStateException  e) {
                    //throw new RuntimeException(e);
                    return(null);
                }
            }
        });
    }

这就是你所说的:

代码语言:javascript
复制
 public webSocketClientEndpoint(URI endpointURI, long timeout) {

        final Future<Session> futureSes = asyncConnectToServer(this, endpointURI);

        try {            
            Session ses = futureSes.get(timeout, TimeUnit.MILLISECONDS);
        } catch(InterruptedException | ExecutionException | TimeoutException  e) {
            System.out.println("Time out...");
        }
    }

参考文献:https://dzone.com/articles/javautilconcurrentfuture

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#get(long,%20java.util.concurrent.TimeUnit)

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28543003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档