3

我正在为我正在创建的 MMORPG 开发套接字服务器,但我不确定如何组织命令和处理程序以提高可读性。

我将从 data[0] 获取命令,例如禁止、踢、识别等。我已经读到您可以使用 HashMap 并拥有一个接口命令,并为实现命令的每个处理程序/命令创建一个新类. 然后,您将创建一个 HashMap 并从那里开始。我也读过你可以反思。我想做一个有经验的程序员会做的事情。

客户端类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client implements Runnable {

    private Socket socket;
    private Server server;
    private boolean isConnected;
    private BufferedReader in;
    private PrintWriter out;

    public Client(Socket socket, Server server) {
        this.socket = socket;
        this.server = server;
        this.isConnected = true;
        this.in = null;
        this.out = null;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            while (isConnected) {
                String recv = in.readLine().trim();

                if (recv != null) {
                    String[] data = recv.split("%");
                }
            }
        } catch (IOException e) {}
    }

    public synchronized void send(String data) {
        out.println(data);
    }
}
4

1 回答 1

2

您想要的是使用Command Pattern

以下是我将如何使用命令模式来处理来自客户端的命令。

/* Command Exception. */
public class ClientCommandException extends Exception {
    public ClientCommandException(String msg) {
        super(msg);
    }
}

/* The ClientCommand interface */
public interface ClientCommand {
    void execute(Client client, String[] params) throws ClientCommandException;
}

import java.util.HashMap;
import java.util.Arrays;

/* Container for commands */
public class Commands implements ClientCommand {
    private HashMap<String, ClientCommand> cmds;

    public Commands() {
        cmds = new HashMap<String, ClientCommand>();
    }

    public void addCommand(ClientCommand cmd, String name) {
        cmds.put(name, cmd);
    }

    public void execute(Client client, String[] params) throws ClientCommandException {
        ClientCommand cmd = cmds.get(params[0]);
        if(cmd != null) {
            cmd.execute(client, Arrays.copyOfRange(params, 1, params.length));
        } else {
            throw new ClientCommandException("Unknown Command: " + params[0]);
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Client implements Runnable {

    private boolean isConnected;
    private Commands cmds;
    private BufferedReader in;
    private PrintWriter out;

    private class EchoCommand implements ClientCommand {
        public void execute(Client client, String[] params) throws ClientCommandException {
            StringBuilder b = new StringBuilder("Echo back:");
            int len = params.length;
            for(int i = 0; i < len; i++) {
                b.append(' ');
                b.append(params[i]);
            }
            client.send(b.toString());
        }
    }

    private class DisconnectCommand implements ClientCommand {
        public void execute(Client client, String[] params) throws ClientCommandException {
            client.close();
        }
    }

    public Client() {
        cmds = new Commands();
        cmds.addCommand(new EchoCommand(), "echo");
        cmds.addCommand(new DisconnectCommand(), "disconnect");
        /* sub-commands */
        Commands server = new Commands();
        server.addCommand(new EchoCommand(), "print");
        cmds.addCommand(server, "server");
        isConnected = true;
    }

    public void addCommand(ClientCommand cmd, String name) {
        cmds.addCommand(cmd, name);
    }

    public void close() {
        isConnected = false;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out, true);

            while (isConnected) {
                String recv = in.readLine().trim();

                if (recv != null) {
                    String[] data = recv.split("%");
                    try {
                        cmds.execute(this, data);
                    } catch(ClientCommandException e) {
                        /* Return some error back to the client. */
                        out.println(e.toString());
                    }
                }
            }
        } catch (IOException e) {}
    }

    public synchronized void send(String data) {
        out.println(data);
    }

    public static void main(String[] args){
        Client client = new Client();
        System.out.println("Start Client.");
        client.run();
    }
}
于 2013-05-27T01:21:17.327 回答