2014-03-04 85 views
0

作为本周实验的一部分,我假设将基于套接字的聊天应用程序转换为RMI。到目前为止,我设法将服务器和客户端连接在一起并在它们之间传输数据,但传输并不连续。我的意思是,当客户端首次连接服务器时,它会播放一条消息“X已经进入了对话”,但仅此而已。之后我输入的任何内容都不会播出。我即将拔出头发。请帮忙。将套接字聊天转换为RMI聊天

public class ChatServer extends UnicastRemoteObject implements ChatMessage { 

private static final long serialVersionUID = 1L; 
private String sender; 
private String message; 
private ChatMessageType t; 

public ChatServer() throws RemoteException { 
    super(); 
} 

@Override 
public void Message(String sender, ChatMessageType t, String message) 
     throws RemoteException { 
    this.sender = sender; 
    this.message = message; 
    this.t = t; 
} 

@Override 
public String getSender() throws RemoteException { 
    return sender; 
} 

@Override 
public String getMessage() throws RemoteException { 
    return message; 
} 

@Override 
public ChatMessageType getType() throws RemoteException { 
    return t; 
} 

public String ToString() throws RemoteException{ 
    String strMessage; 

    switch (t) { 
    case SETUP: 
     strMessage = sender + " has entered the conversation."; 
     break; 
    case TEARDOWN: 
     strMessage = sender + " has left the conversation."; 
     break; 
    case MESSAGE: 
     strMessage = sender + ": " + message; 
     break; 
    default: 
     strMessage = ""; 
    } 

    return strMessage; 
} 

// driver. 
public static void main(String arg[]) { 
    try { 
     ChatServer c = new ChatServer(); 
     Registry registry = LocateRegistry.createRegistry(1099); 
     registry.rebind("Server", c); 
     System.out.println("Server bound in registry"); 
    } catch (Exception e) { 
     System.out.println("Server error: " + e.getMessage()); 
     e.printStackTrace(); 
    } 
} 

}

public class ChatClient implements ActionListener { 


// static private Socket c; 

static ChatMessage obj = null; 

// static private ObjectInputStream in; 
// static private ObjectOutputStream out; 

static private String name; 
static private String host; 
static private Integer port; 


/** 
* Launches this application 
*/ 
public static void main(final String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 

      if (args.length != 3) { 
       System.out 
         .println("Client requires exactly three args to run."); 
       System.exit(-1); 
      } 

      name = args[0]; 
      host = args[1]; 
      port = new Integer(args[2]); 

      final ChatClient application = new ChatClient(); 
      application.getJFrame().setVisible(true); 

      try { 
       System.out.println("client: connecting to server..."); 
       // c = new Socket(host, port); 
       obj = (ChatMessage) Naming.lookup("//" + host + ":" + port 
         + "/Server"); 
       System.out.println("client: connected!"); 
      } catch (Exception e) { 
       System.out.println("client: " + e.getMessage()); 
       System.exit(-1); 
      } 

      try { 
       // out = new ObjectOutputStream(c.getOutputStream()); 
       // in = new ObjectInputStream(c.getInputStream()); 

       // announce to other clients that you're here 
       // out.writeObject(new ChatMessage(name, 
       // ChatMessageType.SETUP, "")); 
       obj.Message(name, ChatMessageType.SETUP, ""); 
      } catch (Exception e) { 
      } 

      // set up the client's listener as an anonymous thread that's 
      // always running 
      // new Thread(new Runnable(){ 
      // public void run() 
      // { 
      // while(true) 
      // { 
      try { 
       System.out.println(name + ": waiting for data"); 
       ChatMessage m = (ChatMessage) Naming.lookup("//" + host 
         + ":" + port + "/Server"); 
       System.out.println(name + ": data received"); 
       application.updateTextArea(m.ToString()); 
      } catch (Exception e) { 
      } 
      // } 
      // } 
      // }).start(); 
     } 
    }); 
} 

public void updateTextArea(final String message) { 
    conversation.setText(conversation.getText() + message + "\n"); 

    // this will guarantee that the bottom of the conversation is visible. 
    conversation.setCaretPosition(conversation.getText().length()); 
} 

// send button has been pressed, send the message to the server. 
public void actionPerformed(ActionEvent e) { 
    if (send.getText().equals("Send")) { 
     try { 
      System.out.println(name + ": sending data"); 
      // ChatMessage m = new ChatMessage(name, 
      // ChatMessageType.MESSAGE, message.getText()); 
      // out.writeObject(m); 
      obj.Message(name, ChatMessageType.MESSAGE, message.getText()); 
      message.setText(""); // clear the text box. 
      System.out.println(name + ": data sent"); 
     } catch (Exception ex) { 
      // TODO Auto-generated catch block 
      ex.printStackTrace(); 
     } 
    } 
} 

}

enum ChatMessageType{ 
SETUP, 
MESSAGE, 
TEARDOWN 
}public interface ChatMessage extends Remote{ 

public String getSender() throws RemoteException; 
public String getMessage() throws RemoteException; 
public ChatMessageType getType() throws RemoteException; 
public void Message(String sender, ChatMessageType t, String message) throws RemoteException; 
public String ToString() throws RemoteException; 
+0

所有的GUI代码都是不相关的。没有人会穿过这一切。请删除它并替换显示潜在问题的SCCCE。 – EJP

+0

不要忽略异常。打印它们,以及它们的堆栈痕迹。我没有看到你期待的事情发生。 ToString()是唯一真正在这里做任何事情的远程方法。你需要重新考虑这一点。远程对象不是一条消息,它是某种服务器。消息是你通过远程API来回传递的信息。 – EJP

回答

0

我意识到这个问题是很老的,你可能想通了这个答案,但是,我想我会分享的方法我从Java套接字转到RMI。也许这对于那些想要做同样事情的人来说很有用。

我基本上将套接字部分抽象成表示主机间通信路径的“Tunnel”对象。隧道由若干“通道”组成,代表源和目的地之间的单向通信。

您可以在我的博客查看更多详细信息:http://www.thecodespot.com/?p=1