我正在用Java构建一个小型的聊天室应用程序。
我在这里试图通过静态ClientGUI引用成员发送当前类ClientGUI实例(this)。 ServerApplication类应该通过常规静态getter(在ServerApplication.main中完成)接收当前的clientGUI参考。
经过一些烦人的调试之后,我仍然无法弄清在收到ClientGUI引用后,服务器端引用为何仍为空(getCurrentClientGuiReference()失败)。
(当然-发送的ref在传输到服务器端之前已初始化)。
是否无法通过本地静态ref成员传输当前ref?
也许我错过了什么?
波纹管是相关的代码。
提前致谢。
客户端:
package chatApplication;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.swing.*;
public class ClientGUI implements StringConsumer, StringProducer
{
//Graphic components
private JFrame frame;
private JButton btConnect,btSend;
private JTextField tfText, tfServerName, tfPort, tfNickName;
private JPanel north,south,center;
ActionListener listener;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
JLabel mainLable = new JLabel();
//Utilities and connection components
private ConnectionProxy consumer = null;
private ConnectionProxy producer = null;
private ClientDescriptor clientDescriptor = null;
//Connection creation switch
private boolean isConnection = false;
//Client details meant for ClientDescriptor
static private String nickname = "Noname";
static private String serverAddress = "127.0.0.1";
static private String port = "1300";
static private ClientGUI currentClientGuiReference = null;
public ClientGUI()
{
frame = new JFrame("Chit & Chat");
listener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == btConnect)
{
if (isConnection == false)
{
ClientGUI.nickname = tfNickName.getText();
ClientGUI.serverAddress = tfServerName.getText();
ClientGUI.port = tfPort.getText();
ClientGUI.currentClientGuiReference = ClientGUI.this;
clientDescriptor = new ClientDescriptor(nickname, serverAddress, port, currentClientGuiReference); // Identical though NOT related to serverapplication's clientdescriptor
consumer = new ConnectionProxy(clientDescriptor, ClientGUI.this);
//Connecting client consumer as a producer
ClientGUI.this.addConsumer(consumer);
//Temporary text
mainLable.setText("Client consumer/producer thread is connected and running!");
}
}
if (event.getSource() == btSend)
{
String outGoingMessageToChat = tfText.getText();
producer.consume(outGoingMessageToChat); //sending outgoing msg to prducer.consume --> writeutf
}
}
};
btConnect = new JButton ("Connect to chat");
btSend = new JButton ("Send Message");
btConnect.addActionListener(listener);
btSend.addActionListener(listener);
tfText = new JTextField(50);
tfPort = new JTextField(10);
tfServerName = new JTextField(20);
tfNickName = new JTextField(10);
tfServerName.setText("127.0.0.1");
tfPort.setText("1300");
tfNickName.setText("Nickname");
north = new JPanel();
south = new JPanel();
center = new JPanel();
north.setBackground(Color.blue);
south.setBackground(Color.gray);
center.setBackground(Color.white);
south.add(tfText);
south.add(btSend);
north.add(tfNickName,BorderLayout.WEST);
north.add(tfServerName);
north.add(tfPort);
north.add(btConnect,BorderLayout.WEST);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing (WindowEvent event)
{
ClientGUI.this.removeConsumer(clientDescriptor);
frame.setVisible(false);
frame.dispose();
System.exit(0);
}
}
);
frame.add(north,BorderLayout.NORTH);
frame.add(center,BorderLayout.CENTER);
frame.add(south,BorderLayout.SOUTH);
}
public void go()
{
ClientGUI.currentClientGuiReference = ClientGUI.this;
frame.setSize(700,700);
frame.setVisible(true);
mainLable.setText("Hey! " +
"Please enter a nickname, Server Address and a port in the text fields above" +
" and press 'Connect to chat'");
center.add(mainLable);
frame.add(center, BorderLayout.WEST);
if (isConnection == true)
{
mainLable.setText("Your details were sent.");
}
}
@Override
public void addConsumer(StringConsumer consumer)
{
this.producer = (ConnectionProxy)consumer;
//All actions completed - client thread producer/consumer is running.
isConnection = true;
}
@Override
public void removeConsumer(StringConsumer sc)
{
consumer.removeConsumer(clientDescriptor);
}
@Override
public void consume(String inComingMessageFromChat)
{
//Temporary code
mainLable.setText(inComingMessageFromChat);
}
public ConnectionProxy getConsumer()
{
return consumer;
}
public void setConsumer(ConnectionProxy consumer)
{
this.consumer = consumer;
}
/**
* @param args
*/
public static void main(String[] args)
{
ClientGUI clientGUI = new ClientGUI();
clientGUI.go();
}
public static String getNickname() {return nickname;}
public static String getServerAddress() {return serverAddress;}
public static String getPort() {return port;}
public static ClientGUI getCurrentClientGuiReference() {return currentClientGuiReference;}
}
服务器端:
package chatApplication;
import java.net.*;
import java.io.*;
public class ServerApplication {
public static int port = 1300;
public static int backlog = 5;
/**
* @param args
*/
public static void main(String[] args)
{
//Server side network variables
ServerSocket serverSocket = null;
//MessageBoard object
MessageBoard messageBoard = new MessageBoard();
//Client side network variables
Socket clientSocket = null;
ClientDescriptor clientDescriptor = null;
ConnectionProxy clientConnectionProxy = null;
//Client details meant for ClientDescriptor
String clientNickname = "Noname";
String clientServerAddress = "127.0.0.1";
String clientPort = "1300";
ClientGUI clientCurrentGuiReference = null;
try //Creating Server
{
serverSocket = new ServerSocket(port,backlog); //ServerSocket(int port, int backlog)
}
catch(IOException e)
{
e.printStackTrace();
}
while (true)
{
try
{
System.out.println("Server is waiting for Client requests...");
clientSocket = serverSocket.accept(); // A new thread is created for the new client
System.out.println("Client connection request accepted, creating client connection proxy...");
clientConnectionProxy = new ConnectionProxy(clientSocket); //connecting client socket to server
clientConnectionProxy.addConsumer(messageBoard); //Applying specific server system network utilities and connecting proxy to the messageboard
System.out.println("Requesting Client details from Client side...");
clientNickname = ClientGUI.getNickname();
clientServerAddress = ClientGUI.getServerAddress();
clientPort = ClientGUI.getPort();
clientCurrentGuiReference = ClientGUI.getCurrentClientGuiReference();
System.out.println("Creating Client Descriptor...");
clientDescriptor = new ClientDescriptor(clientNickname, clientServerAddress, clientPort, clientCurrentGuiReference);
clientDescriptor.addConsumer(messageBoard);
messageBoard.addConsumer(clientDescriptor);
clientConnectionProxy.start();//Start client connection's thread running
System.out.println("Client thread started...");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
最佳答案
我认为static doesn't do what you think it does。如果Client和Server分别运行(例如在两个不同的进程和两个不同的JVM中),那么为任何对象分配任何变量的数量将使Client和Server都可以看到相同的值/对象。您必须使用某种方式在流程之间进行通信。
一旦设法将ClientGUI传递到服务器,我怀疑您将能够以所需的方式使用它。 ClientGUI也是一个对象,无法在客户端和服务器之间进行通信。您也必须自己进行管理。