我想使用 WCF 启用双向通信,而无需在客户端上打开端口。
我正在开发类似 P2P 应用程序(类似于 teamviewer/logmein),您无需打开端口即可进行通信。
如何在不需要在客户端打开端口的情况下通过 HTTP/HTTPS 实现双向通信?
注意:端口 80 可以在服务器中打开...没有问题。
谢谢
最佳答案
您提到的那些系统的工作原理如下。他们首先尝试让客户端 A 和客户端 B 通过一系列不同的拓扑直接通信,这些拓扑基本上要求其中一个允许传入连接,如果失败,他们会求助于充当中间人的第三方。因此,客户端 A 与服务器对话并向其发送客户端 B 的消息。然后客户端 A 将发回给它的消息作为响应返回。客户端 B 将消息发送到服务器,它从服务器返回客户端 A 的消息。这样,客户端 A 和 B 始终启动连接,并且不需要为传入流量打开端口。
如果我对你的情况理解正确,你总是希望中间的人。为此,您必须编写一个提供所有相关方法的 WCF 服务。例如像
- void SendMessageToClient(Guid senderId, Guid recipientId, Message msg)
- Message[] GetMessages(Guid recipientId)
然后让这些方法分别从某个地方(例如数据库或队列等)存储和检索这些 Message 对象。
然后编写一个使用 HTTP 绑定(bind)连接到 WCF 服务的客户端,并调用服务器上的方法并处理结果。
希望你能理解
- a) 这不是一种非常有效的沟通方式。
- b) 很难测试和调试并理解发生了什么,因为涉及的各方太多,并且通信是异步的,存在于 3 个不同的进程中。
- c) 它在通信之上添加了一个额外的层,因此当您处理基础设施位时以及当您正在处理实际协议(protocol) clientA 和 clientB 在 Message 对象中相互交谈。
伪(代码)示例
在这个例子中,我假设消息对象只是一个字符串,唯一的命令是“whattimeisit”,响应是字符串形式的本地时间
- ClientA 调用 server.SendMessageToClient("clientA", "clientB", "whattimeisit");
- 服务器将此消息存储在 ID 为 1 的数据库中
- ClientB 调用服务器 GetMessages("clientB");
- 服务器检索 ID 为 1 的消息
- ClientB 收到“whattimeisit”作为响应
- ClientB 调用 server.SendMessageToClient("clientB", "clientA", "19:50:12");
- 服务器将此消息存储在 ID 为 2 的数据库中
- ClientA 调用服务器 GetMessages("clientA");
- 服务器检索 ID 为 2 的消息
- ClientA 收到“19:50:12”作为响应
关于WCF绕过防火墙的两种HTTP通信方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1317697/