【问题标题】:How can I reuse a server-side TCP endpoint for multiple consumers?如何为多个消费者重用服务器端 TCP 端点?
【发布时间】:2017-09-18 00:42:36
【问题描述】:

我是一个试图理解 TCP 的初学者,我正在使用 Rust。如果我创建一个新的监听器并将其绑定到一个地址

let tcplistener = TcpListener::bind("127.0.0.1:55555").unwrap();

我可以在127.0.0.1:55555 和客户端上的其他一些端点之间建立tcplistener.accept() 新连接。

在我的例子中,tcplistener 存在于一个表示插件的结构的实例中。每个插件都应该可以通过其自己的浏览器选项卡进行控制。每个插件有一个连接(端点对),一个端点总是127.0.0.1:55555。插件在具有非阻塞侦听器和流的单个线程中运行。我使用 websockets,但我不确定这个问题是否特定于 websockets。

我现在做的是

  • 实例化插件A
  • 接受从浏览器选项卡到插件 A 的第一个连接
  • 之后,将插件 A 中的 tcplistener 字段分配给具有任意操作系统分配端口的新创建的侦听器

这似乎有效;如果我之后实例化一个新插件 B,我可以创建一个绑定到 127.0.0.1:55555 并接受连接的侦听器。如果我不创建具有不同地址/端口的新侦听器,则会收到“地址已在使用”错误。

这显然不是一个好的解决方案,因为它无缘无故地占用了所有其他端口。有没有更好的办法?

评论说:

为什么每个插件都有一个TcpListener?为什么不用监听器一个组件,调用accept,然后将返回的TcpStream 交给每个构建的插件?

这听起来不错,但是TcpListener 将存储在哪里,它如何传递流?我看到的存储可能性:

  • 主机。我无法修改插件宿主,我只是插件作者。
  • 一个专用插件。我看到的问题是插件无法访问存储在另一个插件中的任何信息,所以我不知道该怎么做。
  • 一个单独运行的进程。我可以想象单独运行一个服务器并让插件成为客户端。用户可以将他们的浏览器连接到服务器,服务器以某种方式代理插件。听起来很合理,但这里的不便之处在于插件用户必须将服务器作为单独的包安装。所以我真的很想避免这种情况。虽然我认为启动服务器可以在插件实例化时自动完成,但也许这就是要走的路?

【问题讨论】:

  • 第一个建议 (Option) 有效!这真是太棒了!我根本不了解 Option 的性质,我必须更彻底地阅读文档。到目前为止,它仅用于空指针。我怎样才能接受这个作为答案?关于实例化的建议:有趣的一点,我还没有完全考虑清楚。我的猜测是实例化只能从主机完成。如果它在技术上是可行的,那是不寻常的,因为我没有在其他地方看到它(当然,这并不意味着什么,我是初学者)。顺便说一句,这都是关于 LV2 音频插件标准的。
  • 感谢链接,看起来很有趣!

标签: tcp websocket rust


【解决方案1】:

如果我正确理解您的所有限制,一种解决方法是使用OptionOption 恰好用于“某事或非某事”的情况。

在这里,您可以拥有Option<TcpListener>。在新初始化的插件上,这将被设置为Some(...),一旦被接受,将转换为None

这确实有很多缺点:

  • 有一段时间没有听众。
  • 你必须处理听众是None的可能性。
  • 在第一个插件接受某些内容之前,您不能启动第二个插件。

某种父子关系可能更好,如果可能的话,甚至限制为单例插件。

【讨论】:

  • 选项,是的!关于缺点的好点。特别是第三个,我完全没有考虑过。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 2010-09-17
  • 2015-02-14
相关资源
最近更新 更多