简体   繁体   English

如何设计多客户端/服务器应用程序?

[英]How to design a multi-client/server application?

In a socket-based application (client/server), I want to make the server perform as a proxy(manager) to handle several clients, and to get the message from one client and send it to the client, identified by an ID. 在基于套接字的应用程序(客户端/服务器)中,我想使服务器充当代理(管理器)来处理多个客户端,并从一个客户端获取消息并将其发送到由ID标识的客户端。

How can I know the required client running on different thread, how can I get the socket of the associate client that the id represents? 如何知道所需的客户端在不同的线程上运行,如何获取ID代表的关联客户端的套接字?

Just keep an in-memory hashmap of some sort of client-id to the java.net.Socket object that represents that client's socket. 只需在代表该客户端套接字的java.net.Socket对象中保留某种客户端ID的内存哈希图即可。 You need to come up with some way of assigning client IDs, either client supplied, or server-supplied through some authorization scheme. 您需要提出一种分配客户端ID的方法,这些ID可以是客户端提供的,也可以是通过某种授权方案由服务器提供的。

When a message comes in for a client ID, grab the socket from the map and send it a message. 当收到有关客户端ID的消息时,请从地图上获取套接字并向其发送消息。 This map needs to be stored in a singleton-type object, and needs to be properly synchronized. 该映射需要存储在单例类型的对象中,并且需要正确同步。 Use a concurrent hash map. 使用并发哈希图。 Also, socket reads and writes would need to be synchronized if you're going multi-threaded. 另外,如果要使用多线程,则套接字读取和写入将需要同步。

I have posted some example code as a github gist . 我已经发布了一些示例代码作为github要点 It's a bit different than I explained above. 这与我上面解释的有点不同。 I don't store sockets in the map, I store client handlers which have the socket. 我不在地图中存储套接字,而是存储具有套接字的客户端处理程序。 Also, socket reads don't need synchronization: each clients has its own thread which is the only thread reading from the socket. 另外,套接字读取不需要同步:每个客户端都有自己的线程,这是从套接字读取的唯一线程。 Socket writes do need to be synchronized though, because the thread of the sending client is writing to the socket of the receiving client. 但是,套接字写操作确实需要同步,因为发送客户端的线程正在写入接收客户端的套接字。

You're probably better off using something like JBoss Netty rather than rolling your own though. 您最好使用JBoss Netty之类的东西,而不要自己动手。

您可以保留很多有关ID的信息,因此每次连接时,您都会像ip一样保存并保存正在运行的线程,然后使用像hashmap一样将id链接到所有这些信息,然后就可以轻松地获取它的线程正在运行并将信息发送到正确的客户端

Save the messages to be delivered into a database, and make your threads check the database for new messages to be delivered to "their" clients on a regular basis. 将要传递的消息保存到数据库中,并使您的线程定期检查数据库是否有新消息传递给“其”客户端。

If you do not want a dedicated database for the messages, build a flat file with simple ClientID->Socket mappings and use it like a "telephone book" kind of lookup system. 如果您不希望消息有专用的数据库,请使用简单的ClientID-> Socket映射构建一个平面文件,并将其用作“电话簿”类型的查找系统。 Depending on the amount of clients you are planning to add, each thread could pre- and regularily reload such a file into it's memory for faster access... 根据您计划添加的客户端数量,每个线程可以预先定期将此类文件重新加载到其内存中,以加快访问速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM