Как начать общение только между двумя клиентами и двумя клиентами, используя апплеты и сервлеты? - PullRequest
0 голосов
/ 02 апреля 2010

Сначала я должен извиниться за мои предыдущие вопросы. (Вы можете проверить мой профиль для них) Они, казалось, задавали больше вопросов, чем давали ответы. Поэтому я задаю актуальный вопрос, который положил начало всем этим абсурдным вопросам.

Я пытаюсь создать чат-апплет. До сих пор я кодировал апплет, сервлет и связь между апплетом и сервлетом. Код на стороне сервлета таков, что я смог установить чат между клиентами с помощью апплетов, но код больше походил на функцию широковещательной передачи, то есть все клиенты будут общаться друг с другом. Это было моей первой целью, когда я начал разрабатывать чат-апплет. Второй шаг - общение только между двумя конкретными пользователями, как и в любом другом приложении чата. Так что это была моя идея для этого:

  1. Я создаю экземпляр сервлета с кодом широковещательной рассылки.
  2. Затем я передаю адрес этого экземпляра соответствующим клиентам.
  3. 2 клиентских апплета используют адрес для чата. Технически код является «широковещательным», но так как к нему подключено только 2 клиента, он предоставляет возможность общения между двумя клиентами. Таким образом, группы из 2 клиентов имеют разные экземпляры одного и того же сервлета, и каждый экземпляр обрабатывает обмен сообщениями между двумя клиентами с максимальным значением

Однако, как и предполагалось, идея не осуществилась!

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

Теперь я знаю, как использовать request.getSession (). Поэтому я установил сеанс для апплета в его теге param и использую его для дальнейшей связи с сервлетом. Но как мне использовать эти данные, чтобы установить чат между двумя клиентами? Как я уже писал ранее, у меня есть код для чата broadcast_all:

public class CustomerServlet extends HttpServlet {

public String getNextMessage() {
    // Create a message sink to wait for a new message from the
    // message source.
    return new MessageSink().getNextMessage(source);
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    ObjectOutputStream dout = new ObjectOutputStream(response.getOutputStream());
    String recMSG = getNextMessage();
    dout.writeObject(recMSG);
    dout.flush();
}

public void broadcastMessage(String message) {
    // Send the message to all the HTTP-connected clients by giving the
    // message to the message source
    source.sendMessage(message);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    try {
        ObjectInputStream din= new ObjectInputStream(request.getInputStream());
        String message = (String)din.readObject();
        ObjectOutputStream dout = new ObjectOutputStream(response.getOutputStream());
        dout.writeObject("1");
        dout.flush();
        if (message != null) {
            broadcastMessage(message);
        }
        // Set the status code to indicate there will be no response
        response.setStatus(response.SC_NO_CONTENT);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
MessageSource source = new MessageSource();
}

class MessageSource extends Observable {
public void sendMessage(String message) {
    setChanged();
    notifyObservers(message);
}
}
class MessageSink implements Observer {
String message = null;  // set by update() and read by getNextMessage()
// Called by the message source when it gets a new message
synchronized public void update(Observable o, Object arg) {
    // Get the new message
    message = (String)arg;
    // Wake up our waiting thread
    notify();
}
// Gets the next message sent out from the message source
synchronized public String getNextMessage(MessageSource source) {
    // Tell source we want to be told about new messages
    source.addObserver(this);
    // Wait until our update() method receives a message
    while (message == null) {
        try {
            wait();
        } catch (Exception e) {
            System.out.println("Exception has occured! ERR ERR ERR");
        }
    }
    // Tell source to stop telling us about new messages
    source.deleteObserver(this);
    // Now return the message we received
    // But first set the message instance variable to null
    // so update() and getNextMessage() can be called again.
    String messageCopy = message;
    message = null;
    return messageCopy;
}
}

На стороне апплета у меня есть поток, который подключится к сервлету выше, используя метод GET для получения новых сообщений. Он использует цикл while и блокируется, пока не получит сообщение от сервлета. Основной поток связывается с сервлетом, используя метод POST всякий раз, когда клиент вводит сообщение. В настоящее время все клиенты общаются со всеми. Я хочу использовать те же методы, которые использовались выше (или, если возможно, любым другим способом), чтобы установить чат только между двумя клиентами и двумя клиентами. Я мог бы иметь другую ветку в апплете, чтобы проверить, хочет ли кто-либо из пользователей пообщаться с ним, а затем обменяться некоторыми данными, чтобы только эти два пользователя общались ...

Затем я попытался изменить свой код широковещательной рассылки. В этом коде я использовал классы, которые реализовали интерфейсы Observer и Observable. Итак, следующая идея, которую я получил, была:

  1. Создать новый объект класса Observable (скажем, class_1). Этот объект будет общим для 2 клиентов.
  2. 2 клиента, которые хотят общаться в чате, будут использовать один и тот же объект class_1.
  3. 2 других клиента будут использовать другой объект class_1.

Но проблема здесь заключается в классе, который реализует интерфейс Observer (скажем, class_2). Так как наблюдатели контролируют один и тот же тип класса, а именно class_1, как мне установить наблюдателя, отслеживающего один объект class_1, а другого наблюдателя, отслеживающего другой объект того же класса class_1 (потому что notifyObservers () уведомит всех наблюдателей, и я могу ' назначить конкретного наблюдателя определенному объекту)?

Сначала я решил задать отдельные проблемы, такие как создание экземпляров сервлетов, использование объектов наблюдаемых и наблюдателей и т. Д. В stackoverflow ... но я запутался еще больше. Кто-нибудь может дать мне идею, как установить чат только между двумя клиентами? (Я использую Http, а не сокеты или RMI).

С уважением, Митхун.

P.S. Спасибо всем, кто ответил на мои предыдущие (абсурдные) запросы. Я должен был указать цель раньше, чтобы вы, ребята, могли помочь мне лучше.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2010

Вам необходимо сохранить всех подключенных пользователей в Map<String, User> в приложении , используя ServletContext#setAttribute(). String обозначает уникальный идентификатор пользователя (никнейм чата?). Вам также необходимо сохранить определенный чат User в области действия session , используя HttpSession#setAttribute(). Вам также необходимо сохранить другого пользователя в отдельных чатах в Map<String, User> в области сеанса рассматриваемых пользователей. Вы можете получить атрибут методом getAttribute().

Таким образом, вы узнаете, какие пользователи все доступны и какой пользователь находится в текущем сеансе и с какими пользователями он индивидуально общается.

0 голосов
/ 13 апреля 2010

Это грубый способ сделать это, но я просто не смог найти подходящее решение. Я сделал так, что все пользователи подключились к сервлету с кодом широковещательной передачи. Каждый пользователь должен знать, с каким другим пользователем он общается. Следовательно, при отправке сообщения пользователь добавляет к сообщению свое имя и имя пользователя, с которым он общается. Так как это код широковещательной рассылки, каждый подключенный пользователь получит сообщение. После получения сообщения пользователь анализирует сообщение, чтобы получить пользователя, который отправил сообщение, и имя пользователя, для которого предназначено сообщение. Он сравнил бы эти два имени с его записями - см. Утверждение жирным шрифтом ранее. При совпадении будет отображаться сообщение, иначе игнорировать его.

Опять же, это грубый способ сделать это, и я уверен, что есть лучшее решение.

...