Как мне создать сервер rmi, который будет принимать только одно соединение за раз? - PullRequest
2 голосов
/ 18 июня 2011

Я пишу пару клиент-сервер в java, используя rmi java. Я хочу, чтобы сервер прослушивал соединение, и пока подключен один клиент, сервер должен отклонять любые другие клиенты, которые пытаются подключиться.

Ответы [ 3 ]

2 голосов
/ 18 июня 2011

Вам потребуется запустить реестр RMI в коде, используя http://download.oracle.com/javase/6/docs/api/java/rmi/registry/LocateRegistry.html#createRegistry%28int,%20java.rmi.server.RMIClientSocketFactory,%20java.rmi.server.RMIServerSocketFactory%29, и написать пользовательский RMIServerSocketFactory , который возвращает ServerSocket, который принимает только одно соединение.

EDIT:с коллажем LocateRegistry.createRegistry и http://download.oracle.com/javase/1.5.0/docs/guide/rmi/hello/Server.java с добавлением небольшого дополнительного кода (обратите внимание, что я не компилировал это, поэтому вам нужно будет самостоятельно разобраться с любыми ошибками компиляции;предназначен для того, чтобы показать вам общее использование):

РЕДАКТИРОВАТЬ 2: исправлено, чтобы включить предложение @ EJP (подробнее см. this ).

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello {

    public Server() {}

    public String sayHello() {
    return "Hello, world!";
    }

    public static void main(String args[]) {

    try {
        Server obj = new Server();
        RMIClientSocketFactory csf = new RMIClientSocketFactory() {
            @Override
            public Socket createSocket(String host, int port) throws IOException {
                InetAddress addr = InetAddress.getByName(host);
                if (addr.equals(InetAddress.getLocalHost())) {
                    return new Socket(addr, port);
                } else {
                    throw new IOException("remote socket bind forbidden.");
                }
            }
        };
        RMIServerSocketFactory ssf = new RMIServerSocketFactory() {
            @Override
            public ServerSocket createServerSocket(int port) throws IOException {
                System.out.println("RMIServerSocketFactory().createServerSocket()");
                return new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
            }
        };
        Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0, csf, ssf);

        // Bind the remote object's stub in the registry
        Registry registry = LocateRegistry.createRegistry(uri.getPort(), csf, ssf);

        registry.bind("Hello", stub);

        System.err.println("Server ready");
    } catch (Exception e) {
        System.err.println("Server exception: " + e.toString());
        e.printStackTrace();
    }
    }
}
0 голосов
/ 18 июня 2011

Все, что вам нужно сделать, это объявить ваши удаленные методы как синхронизированные. Тогда только один клиент может ввести его / их одновременно.

0 голосов
/ 18 июня 2011

Один простой доморощенный подход состоит в том, чтобы передать все с помощью одного метода, который отслеживает количество запрашивающих потоков. Если уже запущен запрашивающий поток, может возникнуть исключение. В противном случае запрашивающему потоку разрешается продолжить.

Некоторый код для иллюстрации концепции, но не обязательно реализации ...

public class RequestHandler {

    private boolean activeRequest = false;


    public void handeRequest() throws Exception {
         synchronized(this) {
             if (activeRequest) {
                throw new Exception("Request in progress");
             }
             else {
                 activeRequest = true;
             }
         }

         // delegate to something else to perform the request logic


         synchronized(this) {
            activeRequest = false;
         }
    }

}

...