服务器-客户机模型中的Java网络

服务器-客户机模型中的Java网络,java,client-server,Java,Client Server,我有一个关于使用服务器-客户机模型在网络中等待消息的问题 您可以将收到的消息区分为两种不同的类型: 临时消息,例如“用户已登录”,与客户端中的任何其他内容无关 响应消息,例如当您自己尝试登录时 我的问题是关于后者,即我使用这个方案: 向服务器发送登录请求(以“登录用户名密码加密”的形式) (客户端)等待服务器响应或发生5秒超时 (服务器)以“loginconfirmed”或“logindenied”响应 所以我想知道什么是编写此代码的最佳方式,我这里有一些旧代码,但我认为这里的耦合度太高,我已经

我有一个关于使用服务器-客户机模型在网络中等待消息的问题

您可以将收到的消息区分为两种不同的类型:

  • 临时消息,例如“用户已登录”,与客户端中的任何其他内容无关

  • 响应消息,例如当您自己尝试登录时

  • 我的问题是关于后者,即我使用这个方案:

  • 向服务器发送登录请求(以“登录用户名密码加密”的形式)

  • (客户端)等待服务器响应或发生5秒超时

  • (服务器)以“loginconfirmed”或“logindenied”响应

  • 所以我想知道什么是编写此代码的最佳方式,我这里有一些旧代码,但我认为这里的耦合度太高,我已经围绕此代码重写了部分框架(它也驻留在图形类中,这毫无意义,我不应该这样做):

    我使用同步,但我真的不喜欢它,所以如果可能的话,我想避免它。 然而,问题是网络运行在不同的线程中,响应随时可能出现,但是登录过程只需要5秒钟的响应时间

    在不联网的情况下重写代码:

    public class LoginProcedure implements Procedure {
        private final GUI gui;
    
        private LoginPanel loginPanel;
    
        public LoginProcedure(final GUI gui) {
            this.gui = gui;
        }
    
        @Override
        public void start() {
            loginPanel = new LoginPanel(this);
            gui.setPanel(loginPanel);
        }
    
        @Override
        public void finish() {
            Controller.getInstance().finishProcedure();
        }
    
        public void tryLogin(final String username, final char[] password) {
            if (username.isEmpty()) {
                loginPanel.setErrorMessage("Please enter your username.");
                return;
            }
            if (password.length == 0) {
                loginPanel.setErrorMessage("Please enter your password.");
                return;
            }
            gui.setPanel(new LoadingPanel());
        }
    }
    
    在新代码中,它应该从
    gui.setPanel(new LoadingPanel())之后的网络开始


    因此,再次重复主要问题:我如何使Networking类(从服务器读取响应并处理它们的类)在给定的超时时间内,在给定的时刻仅对“loginconfirmed”和“logindenied”作出反应,并将事件重定向到给定的LoginProcedure对象?

    我会将其设计为启用同步/异步消息传递系统

    • 每个可交换消息必须具有UUID和“originID”属性
    • 异步消息只是从发射器发送到接收器
    • 同步消息将其内容发送给接收方,并进入“等待答复”队列。调用线程暂停,或不时ping队列
    • 接收方解析原始消息,准备回复,并用原始消息的ID填充originID属性
    • 回复消息被发送到发射器
    • 发射器解析它,识别它是应答,并向“等待应答”队列发出信号
    • 允许原始线程继续进行,并获得回复
    • 如果没有收到回复,则可能会引发TimeOutException
    public class LoginProcedure implements Procedure {
        private final GUI gui;
    
        private LoginPanel loginPanel;
    
        public LoginProcedure(final GUI gui) {
            this.gui = gui;
        }
    
        @Override
        public void start() {
            loginPanel = new LoginPanel(this);
            gui.setPanel(loginPanel);
        }
    
        @Override
        public void finish() {
            Controller.getInstance().finishProcedure();
        }
    
        public void tryLogin(final String username, final char[] password) {
            if (username.isEmpty()) {
                loginPanel.setErrorMessage("Please enter your username.");
                return;
            }
            if (password.length == 0) {
                loginPanel.setErrorMessage("Please enter your password.");
                return;
            }
            gui.setPanel(new LoadingPanel());
        }
    }