服务器与客户端通信架构

4
我们有一款名为“交易复制”的软件,顾名思义,它用于将一个交易员(发送方)的交易复制到多个其他交易员(接收方)中。它有三个主要组成部分:
1. 发送方客户端。
2. 服务器。
3. 接收方客户端。
发送方 -> 服务器 -> 接收方。
发送器是使用MQL脚本构建的。MQL是一种交易员使用C ++构建的编程语言。由于只有一个发送器,因此发送器代码将交易信息(或信号)推送到服务器。服务器基于PHP,具有简单的MySQL数据库,管理员可以维护转发此信号的用户。
接收器也是使用MQL构建的。但目前它是使用一种独特的技术构建的,为了明确起见,我们对此并不确定,因为我们第一次接触到该代码,原始程序员已经无处可寻(如预期)。所以回到问题上,接收器客户端有一段代码似乎会“轮询”服务器以获取任何更新。MQL使用C ++ lib调用InternetReadFile函数,该函数使用InternetOpenUrlA。现在,MQL每X毫秒向服务器发送请求以查看是否有新信号,并在找到信号时拉取它。如果提供MQL代码有助于解决问题,我可以这样做。
现在是我的问题。
  1. 这是一个好方法吗?如果接收用户增加到数百人,并且每个人每 X 毫秒“轮询”服务器(或者使用 InternetReadFile 做其他事情),取决于 X,它不会在某个时间点消耗掉服务器的 CPU 吗?我看到这被实现为一个 pull 服务,但我认为服务器应该推送这些信息,而不是所有接收客户端不断请求。

  2. 如果上述问题的答案是“这是一个糟糕的方法”,最好的方法是什么?从服务器通过套接字通信向每个接收方推送信号是一个好主意吗?预计会有像“端口转发”和“更改 IP”这样的问题在接收方客户端出现吗?还是可以通过编程方式克服这些问题?

很乐意提供代码和进一步澄清。


对于面临类似问题的任何人。我们研究了MQ、Websockets,最终决定采用WPF:http://msdn.microsoft.com/en-us/library/ms752254.aspx - Aziz
1个回答

4

任何轮询都会引入延迟并生成额外的流量,这是无法避免的。理想情况下,您应该选择直接的解决方案:“套接字到套接字”或使用类似zeromq的异步推送(也是通过套接字,只是抽象化了)。

问题是:当您在交易终端内运行时,是否值得这样做。由于您从终端到服务器再到终端,延迟已经固有。此外,您还将受到接收方执行以及经纪人执行速度的延迟。因此,在市场变动时,您将看到原始和副本之间巨大的差异,这使得解决方案失去了意义。这个功能确实应该由经纪人提供,并在服务器API插件或管理器API中实现。除此之外,大多数经纪人设置:延迟+点差+加价将消耗客户端希望通过复制“好”的交易获得的任何优势。

为了解决网络问题,由于您知道您的客户正在运行mt4,您还知道客户机上应该打开443出站口,因为这是mt4使用的端口。您还可以相当自信地说http(80)也是开放的,特别是因为当前解决方案使用http进行通信。因此,如果您将服务器主机设置为443或80,并且您的发送方和接收方都作为客户端连接到您的服务器,则客户端IP和防火墙设置就不重要了。除此之外,您始终可以实现某种基于文件的配置,以便在安装/故障排除过程中调整客户端端口。最终,无论您是轮询还是异步,您的网络问题都将是相同的,这完全归结为通过套接字的TCP。


谢谢Dmitry。对于“固有延迟”的问题,我们非常了解,但是如果在这个项目的范围内<1秒钟,它会导致接收方的价格滑移量可以忽略不计。ZeroMQ看起来是一个很好的解决方案,可以抽象出套接字。虽然最后一段话没有完全理解。 - Aziz
如果接收方执行延迟在亚秒级别,那么你会非常幸运。假设网络条件理想,在美国境内客户端到服务器的延迟大约为150毫秒。如果你的发送方、服务器或接收方跨越海洋,你需要考虑将近两倍的延迟。两个传输环节就已经超过了半秒钟。再加上MQL非常缓慢,经纪人渴望从中捞取任何零头,你要想达到亚秒级别就非常幸运了。 - Dmitry
在第二段中,我想说的是,至少应该开放出站端口443和80。如果没有开放,客户端将无法进行交易或上网。如果这些端口被阻塞或转发,他们将面临更多不同类型的问题。 - Dmitry
明白了。我同意你关于延迟的观点,但发送方和接收方预计在同一个国家。然而,防止滑点的主要原因将是在复制时使用限价和止损单。无论如何,这是产品所有者需要决定的事情,我们已经传达了所有这些问题。感谢你提供有关此事的建议。干杯。 - Aziz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接