有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c#关于开发基于TCP/IP的消息客户端的建议

我有一个控制电话系统的服务器端协议,我已经实现了一个与之通信的客户端库,现在正在生产中,但是我现在的系统有一些问题,所以我正在考虑重新编写它

我的客户机库目前是用Java编写的,但我正在考虑用C#和Java重新编写它,以允许不同的客户机访问同一个后端

消息以关键字开头,包含若干字节的元数据,然后是一些数据。消息始终以消息结尾字符终止

客户机和服务器之间的通信是双工的,通常采用来自客户机的请求的形式,该请求会引发服务器的多个响应,但也可以是通知。 这些消息被标记为已打开:

C:命令

p:挂起(服务器仍在处理请求)

D:数据作为对

R:答复

B:忙(服务器目前太忙,无法处理响应)

N:通知

我当前的体系结构中,每一条消息都会被解析,并生成一个线程来处理它,但是我发现一些通知的处理顺序不正确,这给我带来了一些麻烦,因为它们必须按照它们到达的相同顺序来处理

双工消息通常采用以下消息格式: 客户->;服务器:命令 服务器->;客户端:挂起(可选) 服务器->;客户端:数据(可选) 服务器->;客户端:响应(消息数据中的第二个条目表示这是否为错误)

我已经使用这个协议一年多了,我从来没有看到过繁忙的消息,但这并不意味着它们不会发生

服务器还可以向客户端发送通知,并且服务器上的事件会自动触发一些响应消息,因此发送这些消息时不会发出相应的命令

一些通知消息将作为消息序列的一部分到达,这些消息是相关的,例如:

通知名称M00001 通知名称M00001 通知名称M00000

字符串M0000X表示有更多数据要来,或者消息到此结束

目前,tcp客户端相当愚蠢,它只生成一个线程,通知订阅服务器上的事件消息已收到,该事件特定于消息关键字和消息类型(因此数据、响应和通知分别处理)。这对数据和响应消息相当有效,但是,由于通知消息似乎以快速顺序到达,因此会导致消息结束在处理包含数据的消息结束之前被处理,从而导致消息数据丢失

鉴于这篇关于系统如何工作的描述写得非常糟糕,您将如何着手编写客户端传输代码

元数据没有消息编号,我无法控制底层协议,因为它是由供应商提供的


共 (3) 个答案

  1. # 1 楼答案

    我只能推荐基于Java的解决方案

    我会使用一些已经成熟的传输框架。我所说的“some”是指迄今为止我唯一与之合作的ApacheMina。然而,它是有效的,而且非常灵活

    对于必须按接收顺序生成的消息,您可以构建队列并将此类消息放入队列中
    为了限制队列的数量,您可以实例化(例如)4个队列,并根据消息排序部分的散列的最后2位(索引0-3)(例如,在消息中包含的客户端id上)将传入消息路由到特定队列

    如果你有更具体的问题,我可以适当地更新我的答案

  2. # 2 楼答案

    我会有一个线程,每个客户端进行解析和处理。这样,处理将按照发送/到达的顺序进行

    如您所述,这些任务不能安全地并行执行。在不同的线程中执行解析和处理可能会增加尽可能多的开销

    如果您的处理相对简单并且不依赖于外部系统,那么单个线程应该能够每秒处理1K到20K条消息

    是否还有其他问题需要解决

  3. # 3 楼答案

    消息必须按接收顺序处理的要求几乎强制了生产者/消费者设计,侦听器从客户端获取请求,解析它们,然后将解析后的请求放入队列。一个单独的线程(使用者)按顺序从队列中获取每条消息,对其进行处理,并向客户端发送响应

    或者,使用者可以将结果放入队列中,以便另一个线程(可能是侦听器线程?)可以将结果发送到客户端。在这种情况下,您将拥有两种生产者/消费者关系:

    Listener -> event queue -> processing thread -> output queue -> output thread
    

    在。NET中,使用BlockingCollection来处理队列,这类事情非常容易实现。我不知道Java中是否有类似的东西

    多消息请求的可能性使事情变得复杂了一点,因为侦听器似乎必须缓冲消息,直到请求的最后一部分出现,然后才能将整个消息放入队列

    对我来说,生产者/消费者设计的美妙之处在于它强制程序的不同部分之间进行硬分离,使每个部分更易于调试,并将共享状态导致问题的可能性降至最低。这里唯一稍微复杂的部分是,您必须将连接(套接字或任何东西)作为在队列中共享的消息的一部分,以便输出线程知道将响应发送到哪里

    我不清楚您是否必须按照收到的顺序处理所有消息,或者您是否只需要按照正确的顺序处理任何特定客户机的消息。例如,如果您有:

    Client 1 message A
    Client 1 message B
    Client 2 message A
    

    在处理来自客户端1的第二条消息之前,可以先处理来自客户端2的第一条消息吗?如果是这样,那么您可以通过使用逻辑上的多个队列来提高吞吐量,每个客户机一个队列。然后,您的“消费者”变成多线程。您只需确保在任何时候每个客户端只处理一条消息