我的 Websocket 需要永远连接

Posted

技术标签:

【中文标题】我的 Websocket 需要永远连接【英文标题】:My Websocket takes forever to connect 【发布时间】:2015-05-22 22:30:04 【问题描述】:

更新 似乎在构造函数中的 org.glassfish.tyrus.core.BaseContainer 中,这两行运行速度超级慢:

this.managedExecutorService = lookupManagedExecutorService();
this.managedScheduledExecutorService = lookupManagedScheduledExecutorService();

在这两种方法的 cmets 中提到 android 是怎么回事,我是否使用了针对桌面的错误 Java 代码?


我使用的代码完全来自:

Tyrus Websocket Documentation: 1.1.2 Client Endpoint

不知何故,连接需要大约 10 秒,特别是在我运行 Eclipse 的调试器时的这一行:

ClientManager client = ClientManager.createClient();

会不会跟这个有关? Potentially similar Stack Overflow Question

我真的迷路了,我觉得我是一个罕见的异类,我试图将 websockets 与 Java 客户端一起使用,而不是使用带有 javascript 的浏览器。

【问题讨论】:

记住在调试模式下运行会减慢速度;优化可能不是最努力的,垃圾收集等。 试用 Tyrus 1.10。 #createClient 不应该花费大量时间,#connectToServer 可以(服务器/网络问题) @Pavel,我正在使用 tyrus-standalone-client-1.10.jar 啊,好的。我看到了 1.1.2,但这实际上是指向 1.9 文档的链接;)无论如何,你能做一些更全面的测量吗?您可以尝试调用 ClientManager.createClient 几千次,看看需要多长时间(没有附加调试器)。如果它超长,可能需要一些时间来处理类路径.. 在致电createClient 之前尝试System.setProperty(javax.naming.InitialContext.INITIAL_CONTEXT_FACTORY, "javax.naming.spi.InitialContextFactory");。它应该很快就会使 JNDI 查找失败。在我的测试中,客户端的创建时间不到 100 毫秒。 (Grizzly 和 Jdk 变体)。 【参考方案1】:

所以问题的原因是 Tyrus 初始化了一个InitialContext,以便在可用的情况下重新使用(预定的)执行器服务。通常,如果没有可用的,这会很快失败(这会记录为调试消息,请参阅下文),但在这种情况下,它仅在尝试初始化无法工作的INITIAL_CONTEXT_FACTORY 后才会失败。要覆盖此行为,请致电 System.setProperty(javax.naming.InitialContext.INITIAL_CONTEXT_FACTORY, "javax.naming.spi.InitialContextFactory") 在创建客户端之前。然后,初始 InitialContext 将尝试创建接口的实例,这很快就会失败。

使用详细日志记录可能会更早发现问题。 Tyrus 不会做很多(调试)日志记录,但在这种情况下,使用jul over logback 的设置可能会显示出潜在问题的早期迹象。作为一般规则:始终确保在遇到奇怪问题时可以查看跟踪/调试日志。

至于源代码中的Android cmets:这只是注意到与“JDK8 compact2 profile”不兼容的平台,通过不直接导入javax.naming.InitialContext类来解决(因为显然它不存在在 compact2 配置文件中),但使用反射代替(另请参阅 TYRUS-242)。

如果您正在创建纯 Java Websocket 客户端,请考虑使用JDK 7 client。 JDK 7 客户端包 (org.glassfish.tyrus:tyrus-container-jdk-client:1.10) 比默认的 (org.glassfish.tyrus.bundles:tyrus-standalone-client:1.10) 要小得多。

当我开始使用带有 Java 客户端的 websockets(我选择 Jetty websocket client API 实现)时,我也觉得自己是个异类。我也开始使用更多嵌入的Tomcat(例如basic-jsp-embed)。当结合这些技术时,您将获得一个强大的(“全双工”)网络解决方案(更类似于点对点而不是客户端-服务器)。希望它会流行起来。 需要记住的一个警告是,一些防火墙会在 30 分钟后断开连接(看起来像 http 连接)(即使连接正在使用中)。因此,为了获得稳定的连接,请确保客户端定期发送 ping 消息以确保连接健康,并在/每 30 分钟内创建一个新连接。

【讨论】:

以上是关于我的 Websocket 需要永远连接的主要内容,如果未能解决你的问题,请参考以下文章

使用WebSocket实现聊天室

使用WebSocket实现聊天室

记一次websocket连接不上问题?

从 C# 程序连接基于 node.js 的 socket.io WebSocket 服务器

使用rabbitmq广播模式来处理集群下的websocket消息推送

基于“广播”或“房间”的 Websocket 策略