回退如何与 socket.io 一起工作?
Posted
技术标签:
【中文标题】回退如何与 socket.io 一起工作?【英文标题】:How does fallback work with socket.io? 【发布时间】:2015-12-29 17:39:02 【问题描述】:我想将WebSocket
与Java
一起使用。问题是,我的服务器通过无法配置的代理与客户端分开。我一直在寻找WebSocket
的实现以及long-polling
等后备选项。我找到了socket.io
,但不知道后备是如何工作的。
在什么情况下会替换WebSocket
,如何替换?
是否还有其他库,例如带有后备实现的 socket.io?我想在Java
找到一个,但我只找到Jetty
。
编辑: 回退是否仅取决于浏览器与 WebSocket 的兼容性?如果失败的原因是代理配置不当,socket.io 是否会将其检测为兼容性故障并因此切换到长轮询(或其他技术)?
回答: 从 v1 开始,socket.io 包含了engine.io,它带来了以下特性:
【问题讨论】:
【参考方案1】:Socket.io 是 websockets 协议的几个实现之一,它的主要卖点 (IMO) 是它的易用性:您不需要编写保活机制或决定哪种传输方式最好,它可以做到给你。
所以,明确一点,socket.io 并没有取代 websocket 协议,它是一个为你实现它的包。
您提到了长轮询。这是 socket.io 使用的一种传输方式。长轮询是基于 HTTP 的,它基本上是请求 --> 等待 --> 响应,等待时间不是很长,因为它可以被 EOF 或陈旧连接上的负载平衡器丢弃。尽管如此,当 websockets 协议(基于 TCP)不可用并且 socket.io 会自动为您重新建立连接时,它仍然很有用。请注意,websockets 是一个相对较新的协议,于 2011 年获得批准,因此较旧的浏览器不支持它。好吧,socket.io 会检测到这一点,然后使用长轮询,因此您不必“担心”它。
一个 websocket 连接从 HTTP 开始,监听同一个端口。例如,http://localhost:8080(只是一个愚蠢的例子)。然后,如果可能,socket.io 会为您切换到 ws://localhost:8080。
我在使用 socket.io 时从未遇到过网络拓扑挑战的问题,因为当 HTTP 端口可用并且可以使用长轮询/websockets 时,它对我有用。
正如您所提到的,具有后备实现的库之一是 netty-socket.io。注意它是如何配置这两种传输的:
public class Configuration
private ExceptionListener exceptionListener = new DefaultExceptionListener();
private String context = "/socket.io";
private List<Transport> transports = Arrays.asList(Transport.WEBSOCKET, Transport.POLLING);
private int bossThreads = 0; // 0 = current_processors_amount * 2
private int workerThreads = 0; // 0 = current_processors_amount * 2
完整代码见here。
Node JS 也有用于 websockets 的库,我在这里提到它只是为了澄清长轮询和 websockets 不是唯一的两种可用传输(可能是 Java 中唯一的):
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
简而言之,socket.io 试图让事情变得尽可能简单,包括不必担心要使用哪些传输,因为它在后台为您完成,但仍可根据需要进行配置。
我希望这个简短的解释对你有帮助!
【讨论】:
确实如此,非常感谢!你会在商业环境中推荐 netty-socket.io 吗?似乎是一致的。优点是 Java 语言,更容易向客户和开发人员提出建议。另一个问题(在 OP 中添加),回退是否仅取决于浏览器与 WebSocket 的兼容性?如果失败的原因是代理配置不当,socket.io 是否会将其检测为兼容性故障并因此切换到长轮询(或其他技术)? 是的,我会回答你所有的问题。 socket.io 的后备工作就像黑魔法:它从可能的最佳连接开始,然后不断降级,直到失败。但是,您要么喜欢它,要么讨厌它。我有同事不喜欢这个功能:他们想编写回退代码,自己保持活动(心跳)。如果是这种情况,那么无论如何,请使用 engine.io,这是 socket.io 的基础。这完全取决于您想自己编写代码或依赖工具的程度。就个人而言,我喜欢 socket.io,但这只是我的看法。 关于 Java:它使用线程池进行连接,大规模使用可能会很昂贵。请注意,线程池基本上是时间切片功能,而不是“真正的”线程(直至 CPU 代码)。如果您的客户数量庞大,并且您对其他工具持开放态度,Node JS 可能更适合您的情况。它的架构是异步的、非阻塞的、单线程的。但这是题外话,因为您的问题是关于 socket.io 的。我添加此评论是因为您询问了 Java。简而言之:您几乎可以在 Java 上做任何事情,但还有其他工具可供选择。祝你好运! 这是一个很好的答案,但你能回答这个问题吗?标题目前歪曲了 stackover 流搜索。问题是,如何?有没有需要做的配置?我们至少可以链接到有示例的文档吗? @arnold 我认为我正在寻找的答案是......它会在后台自动发生,您无需执行任何操作。它是否正确?如果是这样,我想你回答了这个问题,但我觉得问题标题更适合说“socket.io 如何处理自动回退?” .当前的标题可能被假定为“我应该怎么做才能使自动回退工作。”,但是如果 socketio 自己处理它而没有任何额外的工作,那么......也许这个标题应该变得更明确,以便人们在未来不会感到困惑。以上是关于回退如何与 socket.io 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章
Socket.IO 在一个房间内多次发射(与 React.js 一起使用)
让 angular-socket-io 与 Grunt 一起工作