【问题标题】:advice on client - server architecture关于客户端 - 服务器架构的建议
【发布时间】:2010-08-16 09:13:17
【问题描述】:

我正在做一个概念应用证明,也许有一天会成为收入来源。
数据流要求必须是一个客户端-服务器应用程序,信息在客户端之间共享并且应该被持久化。

我有编写独立应用程序的经验,我为应用程序建模并编写了客户端。与服务器的通信只是一个存根。

所以现在我有了一个带有方法调用的 (C#) 接口形式的协议。
其中四个调用用于请求信息,两个用于将数据推送到服务器。
这些数据在我想冷冻干燥并在另一边恢复的类中。

将来我想将客户端移植到其他操作系统,所以我不想做一些我必须从头开始重写服务器的事情,如果我不能避免的话。

我还想以不确定的时间间隔更新客户端中的数据。今天我不知道该怎么做。
我的应用程序是单线程的,Windows 窗体

我的假设是:
* 我将在所有内容下方以某种形式使用 TCP/IP。我必须设置频道,设置 IP 地址和类似的东西,我知道我必须做什么。
* 服务器的前端将是多线程,以允许多个客户端同时与服务器通信。同步将在服务器内部进行。
* 预计数据量,最大:文本 1000 * 1kbyte,100 000 个具有 4 种状态的对象。每天 20 000 次更新。但那是未来的方式。

可能三个最大的问题是
1. 通讯协议。如何将我的方法调用(接口中的方法调用)映射到可以在 TCP/IP 通道上传输的东西?
2. 我需要一个好的模式来序列化读取和写入“数据库”,数据库不需要是sql server。
3. 我能否允许服务器向客户端发送更新,而不使其成为一个只监听套接字的多线程应用程序?

如果需要更多信息,我会很乐意更新我的问题。
提前致谢。
戈尔根

【问题讨论】:

    标签: .net architecture client-server


    【解决方案1】:

    从它的声音来看,WCF 就在你的小巷里。虽然一旦你开始深入研究它,乍一看它可能有点复杂,但事情相当简单。这样,您就可以让框架处理异步调用并连接它的网络端。

    就服务器向客户端发送更新而言,您需要查看 WCF 中的双工绑定,并在服务器端维护已知(已连接)客户端列表。当然,将所有对客户端的调用包装在 try-catch 块中,因为您永远不知道何时会发生打嗝并且客户端突然无法访问。

    【讨论】:

    • 我已经开始关注WCF(Windows Communication Fundation)了。我想如果我选择这种方式,我将被绑定到.NET,我无法为其他操作系统开发。是这样吗?另外,WCF,它也能解决我的问题 2 和 3 吗?
    • 由于您将问题标记为 .NET,我认为这就是您要寻找的方向。但是,是的,如果您选择 WCF,您将绑定到服务器上的 .NET。根据您选择的绑定,您可能能够拥有非 .NET 客户端。根据您选择的绑定(这需要是双工绑定,因此使用 .NET 客户端最容易实现),WCF 是#3 的可行答案。至于 #2,我不确定您期望与具有数据库后端的独立应用程序有何不同。
    • 感谢您的澄清,我只是想感受一下解决方案的灵活性,我不得不说我有一些相互矛盾的目标,让某些东西发挥作用并使其适应未来。 #2 如果我为一个客户提供服务,而另一个客户想要得到服务,我必须启动一个新线程或拒绝第二个客户,也许把它放在等待名单上。然后我有两个线程可能想要写入相同的数据并且需要一些锁或任何东西。也许它发生在 WCF 的幕后,但它必须在某个地方完成。
    • 就多个客户端的线程问题而言,WCF 会在后台为您处理。至于从多个客户端访问/写入相同的数据,您需要进一步研究锁定数据方面的“乐观并发”和“悲观并发”。我在这个主题上的常用方法是具有强大审计能力的乐观并发,但这实际上取决于项目的需求。一些 ORM 层框架(如实体框架)也可以为您处理。
    【解决方案2】:

    听起来是 .Net 远程处理的理想选择。

    这将抽象出许多低级字节移位,并允许您使用域级语言编写通信代码。

    【讨论】:

    • .NET 远程处理已弃用。您可能应该将 WCF 用于新项目。
    【解决方案3】:

    我只是想给Agent_9191的回答加点肉,记录一下我为后人采取的步骤:

    问题 1

    • 仔细阅读Getting started tutorial (不,我没有,但我希望我这样做了)

    • 将示例更改为适合我自己的界面

    • 默认生成的代理在很大程度上改变了界面;由于传递机制,所有集合类都被制作成数组,并且您要传输的所有类都被剥离了所有方法。要访问服务器和客户端中的域类,请遵循this post 的建议

    • 将使用的域类必须可通过 System.Runtime.Serializion.dll 中的 [DataContract] 和 [DataMember] 进行序列化

    • 这些WCF samples 也帮助我了解发生了什么

    问题 2

    • 再次创建了一个实现我的接口的类
    • 在服务中添加了一个静态实例
      private static MyManager myManager = new MyManager();

    • 只转发所有来电
      public Project[] GetProjects() { return myManager.GetProjects(); }

    问题 3

    双向合约:How to: Create a Duplex Contract

    我现在将状态保存在内存中,而不是数据库中,当我改变它时,我会重新考虑方法。

    【讨论】:

      【解决方案4】:

      1) 请详细说明这个问题。我不完全明白你到底想在这里解释什么。

      2) 我不确定你的意思是什么(对编程意义上的模式一无所知),但是异步读写这样你只有在有东西时才访问数据库会不会更明智读/写

      3) 是的,这是可行的,但您确实应该创建另一个线程来更新您的客户端。出于几个原因,这是可取的,但主要是您希望尽可能地划分程序逻辑,以便更轻松地隔离软件中的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-27
        • 1970-01-01
        • 2012-07-25
        • 1970-01-01
        • 1970-01-01
        • 2011-02-17
        • 1970-01-01
        相关资源
        最近更新 更多