回退如何与 socket.io 一起工作?

Posted

技术标签:

【中文标题】回退如何与 socket.io 一起工作?【英文标题】:How does fallback work with socket.io? 【发布时间】:2015-12-29 17:39:02 【问题描述】:

我想将WebSocketJava 一起使用。问题是,我的服务器通过无法配置的代理与客户端分开。我一直在寻找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 一起使用)

Socket.io 是不是与 Heroku 一起工作?

让 angular-socket-io 与 Grunt 一起工作

如何使用集群处理 Socket.IO 房间?

如何通过 socks5 代理使用 JavaScript socket.io-client 库?

将 socket.io 与 redux 一起使用