Передача ссылки на объект с использованием RMI - PullRequest
2 голосов
/ 10 сентября 2011

Привет всем,

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

У меня есть несколько клиентов, которые используют Java RMI для установления соединения (register ()) и получения списка клиентов подключений с сервера (get ()). Моя цель - заставить клиентов общаться друг с другом, используя RMI, без необходимости регистрироваться, пока регистрируется только сервер.

Я пытаюсь передать ссылку на объект клиента на сервер.

Я получаю следующую ошибку:

java.rmi.MarshalException: error marshalling arguments; nested exception is: 
    java.io.NotSerializableException: Client

Я не хочу использовать сериализацию (я полагаю), поскольку я не хочу передавать сам объект, но ссылку. Client1 должен иметь возможность отправлять сообщение на Client2, вызывая client2.messsage (String username, String message);

Полагаю, на данный момент я должен показать вам, как я реализовал свой код:

public interface RMIClientIntf extends Remote {
    public void message(String name, String message) throws RemoteException;
    public String getName() throws RemoteException;
}

Предыдущий код - это то, что должны реализовывать все клиенты. Если функция message () вызывается из другого клиента, это означает, что другой класс отправляет сообщение.

Мой класс клиента сам:

public class Client implements RMIClientIntf {
    public Client() throws RemoteException { super(); }
    public String getName() throws RemoteException { }
}

Теперь класс Main, который создает экземпляр клиента, вызывает следующее, чтобы отправить удаленный объект на сервер:

final Client client = new Client();
server.register((RMIClientIntf) client, name);

На стороне сервера метод регистрации определяется как:

public interface RMIServerIntf extends Remote {
    public String register(RMIClientIntf cl, String userName) throws RemoteException;
    public RMIClientIntf[] get() throws RemoteException;
}


public class Server extends UnicastRemoteObject implements RMIServerIntf {
    public String register(RMIClientIntf cl, String userName) throws RemoteException {
        ClientStruct newClient = new ClientStruct(cl, userName);
        /* Store the ClientStruct */
        return new String("SUCCESS");
    }
}

После регистрации каждый клиент запросит список подключенных пользователей. Функция на сервере следующая:

public RMIClientIntf[] get() throws RemoteException {
    RMIClientIntf[] users = new RMIClientIntf[openConnections.size()];
    /* Fill in users from ClientStruct */
    return users;
}

Если клиент также должен был реализовать Serializable, то программа запускается, но когда client2 вызывает client1.message (), метод message () вызывается для client2 и в этот момент выдает NullPointer.

Я просматривал эту ссылку: http://www.exampledepot.com/egs/java.rmi/args_Args.html,, которая подсказала мне, что он должен реализовывать Remote, но не сериализацию для передачи по ссылке. Я не уверен, почему программа жалуется в моем случае.

Я действительно ценю любую помощь, которую могу получить. Я пытался решить эту проблему некоторое время, и я не могу найти никакого решения.

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 10 сентября 2011

вам нужно экспортировать клиента и отправить заглушку на сервер.

edit: это должно работать, оно должно работать так же, как вы экспортировали сервер (но без использования rmiregistry)

server.register((RMIClientIntf) UnicastRemoteObject.exportObject(client,0), name);
1 голос
/ 10 сентября 2011

Вы не можете просто передавать произвольные ссылки через RMI.Клиент должен быть либо Serializable, так что он передается целиком целиком, либо самому экспортированному удаленному объекту, поэтому удаленная ссылка на него передается, и он остается на месте - т.е. это обратный вызов.

РЕДАКТИРОВАТЬ: поскольку последнее, по-видимому, является вашим намерением, все, что вам нужно, это заставить клиента расширять UnicastRemoteObject.

Существует отличный RMI Trail как часть Oracle / Sun Учебные руководства по Java .

...