发布于 2026-01-06 0 阅读
0

从零开始构建消息服务器。(Java)DEV 全球展示挑战赛,由 Mux 主办:展示你的项目!

从零开始构建消息服务器。(Java)

由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!

这要求你对
Java、
ServerSocket 和
ClientSocket 有深入的了解。

我之所以萌生开发这个系统的念头,是因为我无法理解现代应用服务器如何通过单个实例扩展到数百万个连接。于是我开始着手研究。在开发初期,我很难从互联网上找到帮助,所以就写了这份文档……

直接开始编写代码。

这是 ConcurrentServer 开始运行的主类。

class ConcurrentServer{
     public static void main(String[] arg) throws IOException, InterruptedException
     {
            int port;
            if(arg.length == 0){
              port = 8080;
            }
            else{
              port = Integer.parseInt(arg[0]);
            }

            new ConcurrentServer().start(port);
     }
}

等一下……
记住这个List<User> clients。它起着重要的作用。

public class Shared {

    public static List<User> clients = new ArrayList<>();

    public static int count= 0;

    private Shared(){

    }
}

当新用户连接到服务器时,连接对象会被推送到Shared类中的客户端列表中(见下文)。

下面这个User类继承自ClientSocket

public ConcurrentServer{
    public static void main.....
    .
    .
    .
    .

    public void start(int port) throws IOException, InterruptedException{   
        try(ServerSocket server = new ServerSocket(port)){

            Thread channelReaderThread = new Thread(channelReader);
            channelReaderThread.start();

            while(ALWAYS_RUNNING){
                User client = new User(server.accept());
                Shared.clients.add(client);
            }
        }
    }   
}

接下来,我们会阅读可能随时弹出的用户消息。

private void process()
{
    int maxSize = Shared.clients.size();

    for(int i = 0 ; i < maxSize ; i++)
    {
        User user = Shared.clients.get(i);

        queryClient(user, i);
    }
}

private void queryClient(User user,int index)
{
    InputStream inputStream = user.getInputStream();

    if( inputStream.available() <= 0 )
    {
        return;
    }

    ConnectedBy connection = user.getConnectionType();

    connection.handle(user);
}

记住这个人Shared.clients,这是一个数组,其中推送了主线程中已连接的用户。

上述方法process每 100 毫秒触发一次。Java 提供了一个名为 inputStream.available() 的方法,如果用户发送任何消息,该方法的inputStream.available()值将大于 0。此时,我们可以从 inputStream 中读取消息。


一旦你能够读取消息,并且你已经拥有了所有客户端连接,Shared.clients你就可以遍历它并将传入的消息发送给其中的所有客户端。

因此,您现在拥有一个功能正常的即时通讯应用程序。


经过几千个并发连接的测试,大部分时间都能正常发送消息。
但请注意,
偶尔会出现消息丢失的情况,我目前还没找到原因。所以,非常感谢您的帮助。

无论谁理解或不理解,都请留言,我非常乐意与大家交流。

源代码:https://github.com/SrikanthYashaswi/messenger

文章来源:https://dev.to/justhere/building-a-messaging-server-from-scratch-java-30of