如何使用applet和servlet在两个客户端和两个客户端之间启动聊天?

我首先需要为我之前的问题道歉。 (你可以查看我的个人资料)他们似乎提出了更多的问题,而不是给出答案。 因此,我正在制定实际问题,这些问题开始了他们所有荒谬的问题。

我正在尝试设计一个聊天小程序。 直到现在,我已经对applet和servlet之间的applet,servlet和通信进行了编码。 servlet方面的代码使得我能够使用applet在客户端之间建立聊天,但代码更像是广播所有function,即所有客户端将彼此聊天。 这是我开始设计聊天小程序时的第一个目标。 第二步是仅在两个特定用户之间聊天,就像我们拥有的任何其他聊天应用程序一样。 所以这是我的想法:

  1. 我创建了一个具有’broadcast-all’代码的servlet实例。
  2. 然后,我将此实例的地址传递给相应的客户端。
  3. 2个客户端小程序使用该地址然后聊天。 从技术上讲,代码是’broadcast-all’,但由于只有2个客户端连接到它,它提供了两个客户端function之间的聊天。 因此,2个客户端的组具有相同servlet的不同实例,并且每个实例处理最多两个客户端之间的聊天。

然而,正如预测的那样,这个想法没有实现!

我试图创建一个servlet的实例,但唯一的解决方案是在servlet端使用会话,我不知道如何使用此会话进行以后的通信。

我现在知道如何使用request.getSession()。 因此,我在其param标记中为applet设置会话,并将其用于与servlet的进一步通信。 但是如何使用这些数据在两个客户端之间建立聊天? 正如我之前写的,我有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; } } 

在applet方面,我有一个线程,它将使用GET方法连接到上面的servlet以获取新消息。 它使用while循环,并阻塞,直到它从servlet获取消息。 每当客户端输入消息时,主线程使用POST方法与servlet通信。 目前所有客户都与大家聊天。 我想使用上面使用的相同方法(或者如果可能的话,使用任何其他方式)在两个客户端和两个客户端之间建立聊天。 我可能在applet中有另一个线程来检查是否有其他用户希望与它聊天,然后交换一些数据,以便只有那两个用户聊天…

然后我尝试修改我的广播所有代码。 在该代码中,我使用的是实现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()会通知所有观察者,我可以’ t将特定观察者分配给特定对象)?

我首先决定在stackoverflow中询问个别问题,比如如何创建servlet实例,使用observable和observer等对象……但我更加困惑。 任何人都可以给我一个如何在两个客户端之间建立聊天的想法吗?(我使用的是Http而不是套接字或RMI)。

此致,Mithun。

PS感谢所有回复我之前(荒谬)查询的人。 我应该早点说出目的,以便你们能帮助我更好。

您需要使用ServletContext#setAttribute()将所有连接的用户存储在应用程序范围内的Map中。 String表示唯一的用户标识符(聊天昵称?)。 您需要使用HttpSession#setAttribute()将特定的聊天User存储在会话范围中。 您还需要将其他用户存储在相关用户的会话范围内的Map中的单个聊天中。 您可以通过getAttribute()方法获取该属性。

通过这种方式,您可以了解哪些用户都可用,哪些用户在当前会话中以及与哪些用户单独聊天。

这是一种粗暴的方式,但我找不到可行的解决方案。 我做的是我让所有用户连接到具有broadcastAll代码的servlet。 每个用户都会知道正在聊天的其他用户。 因此,在发送消息时,用户会将他的姓名和他正在聊天的用户的姓名附加到消息中。 由于它是broadcastAll代码,因此每个连接的用户都会收到该消息。 在接收到该消息之后,用户将解析该消息以获得发送该消息的用户以及该消息所针对的用户的名称。 它会将这两个名称与其记录进行比较 – 请参阅前面的粗体语句。 如果匹配,它将显示消息,否则忽略它。

再一次,它是一种粗糙的方式,我相信那里有更好的解决方案。