RMI 中的引用传递问题? [复制]

2024-05-18

有人可以告诉我我错在哪里,为什么这个 RMI 聊天应用程序不起作用,目标是通过远程对象或序列化对象实现客户端、服务器和逻辑之间的解耦。


    import javax.swing.*;
    import java.awt.event.*;
    import java.rmi.*;
    import java.rmi.server.*;

    public class ChatClient1 implements ICallback {

        JFrame frame = new JFrame("Chat Client");
        private JTextArea myText;
        private static JTextArea TAUinDispMsg;
        private JScrollPane myTextScroll;
        private JScrollPane TAUinDispMsgScroll;
        private String textString = "";
        private boolean firstMessage = true;
        private static String name = null;

        private static final int HOR_SIZE = 400;
        private static final int VER_SIZE = 150;

        protected static ServerServices chatServer;
        MessageImpl remomsg ; 

        public ChatClient1() throws RemoteException {
            super();

            try {

                this.chatServer = (ServerServices) Naming.lookup("rmi://localhost"
                        + "/ChatServer");

                 UnicastRemoteObject.exportObject(this);
                 chatServer.register(this);
            } catch (Exception e) {
                System.err.println("RemoteException: " + e.getMessage());
                System.exit(0);
            }
            ;

            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    initComponents();
                }
            });

            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    try {
                        if (name != null) {
                            // chatServer.leave(displayChat, name);
                        }
                    } catch (Exception ex) {
                        TAUinDispMsg.append("Exit failed.");
                    }
                    System.exit(0);
                }
            });
        }


        private void initComponents() {

            myText = new JTextArea();

            myTextScroll = new JScrollPane(myText);
            myTextScroll
                    .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            myTextScroll
                    .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            myTextScroll.setMaximumSize(new java.awt.Dimension(HOR_SIZE, VER_SIZE));
            myTextScroll.setMinimumSize(new java.awt.Dimension(HOR_SIZE, VER_SIZE));
            myTextScroll
                    .setPreferredSize(new java.awt.Dimension(HOR_SIZE, VER_SIZE));

            myText.addKeyListener(new java.awt.event.KeyAdapter() {
                public void keyTyped(java.awt.event.KeyEvent evt) {
                    textTyped(evt);
                }
            });

            frame.getContentPane().add(myTextScroll, java.awt.BorderLayout.NORTH);

            TAUinDispMsg = new JTextArea();

            TAUinDispMsgScroll = new JScrollPane(TAUinDispMsg);
            TAUinDispMsg.setBackground(new java.awt.Color(200, 200, 200));
            TAUinDispMsgScroll
                    .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            TAUinDispMsgScroll
                    .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            TAUinDispMsgScroll.setMaximumSize(new java.awt.Dimension(HOR_SIZE,
                    VER_SIZE));
            TAUinDispMsgScroll.setMinimumSize(new java.awt.Dimension(HOR_SIZE,
                    VER_SIZE));
            TAUinDispMsgScroll.setPreferredSize(new java.awt.Dimension(HOR_SIZE,
                    VER_SIZE));
            TAUinDispMsg.setEditable(false);

            frame.getContentPane().add(TAUinDispMsgScroll,
                    java.awt.BorderLayout.CENTER);

            frame.pack();
            frame.setVisible(true);
        }

        private void textTyped(java.awt.event.KeyEvent evt) {

             try {
                remomsg = new MessageImpl();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            char c = evt.getKeyChar();
            if (c == '\n') {
                try {
                    if (firstMessage) {
                        name = textString;
                    //  .join(name);
                        firstMessage = false;
                    } else {
                        remomsg.sendMessage(name, textString);
                    }
                } catch (RemoteException ie) {
                    TAUinDispMsg.append("Failed to send message.");
                    System.err.println(ie.getMessage());
                }
                textString = "";
            } else {
                textString = textString + c;
            }
        }

        @Override
        public void updateClients(final String msg) throws RemoteException {
            // TODO Auto-generated method stub


            System.out.println("Recived Message: " + msg);
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    TAUinDispMsg.append(name + " says: " + msg + "\n");
                }
            });



        }

        public static void main(String args[]) throws RemoteException {

            ChatClient1 ch = null;
            try {
                ch = new ChatClient1();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }




 **ICallback.java: interface for callbacks from server to client**


    import java.rmi.*;

    public interface ICallback extends Remote {
        void updateClients(String msg) throws RemoteException;

    }

我想充当业务逻辑(游戏逻辑)的对象。

 import java.rmi.*;

        public interface Message extends Remote {

            public void sendMessage(String name, String message) throws RemoteException;

            public void updateClients() throws RemoteException;

        }

其实现:

import java.io.Serializable;
import java.rmi.*;
import java.rmi.server.*;
import java.util.ArrayList;
import java.util.Iterator;

import java.util.List;

public class MessageImpl extends UnicastRemoteObject implements Message {
private String name;
private String message;

public MessageImpl() throws RemoteException {
    super();

}
public MessageImpl(ArrayList clients2) throws RemoteException {
    // TODO Auto-generated constructor stub
    this.clients = clients2;

}

static ServerServicesImpl si;
// static ArrayListDemo az;
private List<ICallback> clients = new ArrayList<ICallback>();
// private List<ICallback> clients;

private ServerEngine serverEngine = new ServerEngine();

// Notice this one not called remotely
public void setName(String name) throws RemoteException {
    this.name = name;
}

public String getName() {
    return name;
}

public void setServerList(ServerEngine serverList2) throws RemoteException {
    this.serverEngine = serverList2;

}

public void setClientList(List<ICallback> aclients) throws RemoteException {
    this.clients = (ArrayList<ICallback>) aclients;
    System.err.println("in setClientlist");
}

public ServerEngine getServerList() {
    return serverEngine;
}

// Notice this one not called remotely
public void setMessage(String message) throws RemoteException {
    this.message = message;
}

public String getMessage() {
    return message;
}



public void updateClients() throws RemoteException {


    si = new ServerServicesImpl();
    ArrayList j = si.getClientNames();
    System.out.println(j.size());
    if (clients != null) {
        System.out.println(clients.size());
        for (ICallback aClient : clients) {
            aClient.updateClients(message);
        }

    } else
        System.err.println("Clientlist is empty");

    if (clients != null) {
        System.out.println(j.size());


    } else
        System.err.println("Clientlist is empty");

}

public void sendMessage(String name, String message1)
throws RemoteException {

    setName(name);
    setMessage(message1);
    updateClients();


}

}

用于管理客户端线程的类

import java.lang.*;
import java.util.*;

class ServerEngine {

    private Collection<ICallback> threadList =
                new ArrayList<ICallback>();
    private int counter = 0;

    //  Get the lock on threadList, and wait until the counter is zero - that
    //is, no reads are taking place. Then it's safe to add the thread.

    public synchronized void add(ICallback item) {
        try {
            while (counter > 0) {
                wait();
            }
            threadList.add(item);
        }
        catch (InterruptedException e) {
            System.out.println("Addition interrupted.");
        }
        finally{
            notifyAll();
        }
    }

    // Similarly for removal.
    public synchronized void remove(ICallback item) {
        try {
            while (counter > 0) {
                wait();
            }
            threadList.remove(item);
        }
        catch (InterruptedException e) {
            System.out.println("Removal interrupted.");
        }
        finally {
            notifyAll();
        }
    }

    // Similarly for changing counter
    public synchronized void incCounter() {
        counter++;
        notifyAll();
    }

    public synchronized void decCounter() {
        counter--;
        notifyAll();
    }

    //This is because it would be too much effort to make this class implement
    //Collection, return it's own Iterator etc. etc...\
    //Note it is *not* a bug that it isn't synchronized
    public Collection getCollection() {
        return threadList;
    }
}

Service.java:服务器将注册并绑定的对象。

import java.rmi.*;
import java.util.ArrayList;

public interface ServerServices extends Remote {

    // added so client can register self with server for callbacks
    public void register(ICallback newClient) throws RemoteException;

    public ArrayList getClients() throws RemoteException;

}

ServerServicesImpl.java:服务器的实现端

import java.io.Serializable;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;

class ServerServicesImpl extends UnicastRemoteObject implements ServerServices,
        Serializable {

    String message;
    MessageImpl msgimpl;
    static Vector data = new Vector();

    private static ArrayList Aclients = new ArrayList<ICallback>();
    private static ArrayList testlist;

    public ServerServicesImpl() throws RemoteException {
        super();
        testlist = new ArrayList();

    }

    public synchronized void register(ICallback newClient)
            throws RemoteException {
        data.addElement(newClient);
        Aclients.add(newClient);
        // //serverEngine.add(newClient);

        testlist.add("testing");
        System.out.println("testlist size =" + testlist.size());

        System.out.println(Aclients.size());

        setClientList(Aclients);

    }

    ArrayList getClientNames() {
        // Aclients.add(ic);
        System.out.println("vector size =" + data.size());
        System.out.println("testlist size =" + testlist.size());
        System.out.println(" Aclientlist size =" + Aclients.size());
        return Aclients;
    }

    public void setClientList(ArrayList aclients2) {
        this.Aclients = aclients2;
    }

}

   // the server  which will publish the above remote object

    import java.net.MalformedURLException;
    import java.rmi.*;


    public class ServiceLoader
    {

        public static void main(String[] args)
        {
            try
            {
                // Install a security manager
                System.setSecurityManager(new RMISecurityManager());
                ServerServicesImpl obj = new ServerServicesImpl();

                Naming.rebind("ChatServer", obj);


                System.out.println("ServiceLoader running.");

            }
            catch (MalformedURLException e)
            {
                System.err.println(e.getMessage());
            }
            catch (RemoteException e)
            {
                System.err.println(e.getMessage());
            }
        }

    }

Change

private List<TTTClientRemote> serverList;

To:

private List<TTTClientRemote> serverList = new ArrayList<TTTClientRemote>();

或者在 updateClients() 中的 for() 之前的某个地方初始化它;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RMI 中的引用传递问题? [复制] 的相关文章

随机推荐

  • 如何使用AutoMapper按照类中定义的顺序映射对象?

    给定这两个对象 我使用非常不同的对象来更好地阐明 public class Car public string Brand get set public int Speed get set public class Apple public
  • 在 django ORM 中查询时如何将 char 转换为整数?

    最近开始使用 Django ORM 我想执行这个查询 select student id from students where student id like 97318 order by CAST student id as UNSIG
  • 如何用python脚本控制TP LINK路由器

    我想知道是否有一个工具可以让我连接到路由器并关闭它 然后从 python 脚本重新启动它 我知道如果我写 import os os system ssh l root 192 168 2 1 我可以通过 python 连接到我的路由器 但是
  • OpenCV Mat 和 Leptonica Pix 之间的转换

    我需要在 C 中在 OpenCV Mat 图像和 Leptonica Pix 图像格式之间进行转换 这用于 8 位灰度图像的二值化 我发现发现了 ikaliga的回答 https stackoverflow com a 25929320 2
  • 在 Swift 中使用 CommonCrypto 解密时出现问题

    我在一家Swift only加密 解密Extension for String and NSData 并且 crypt 部分的工作基于 Zaph 在链接问题中提供的答案 在 Swift 中使用 CCCrypt CommonCrypt 时出现
  • Python 中的哈希映射

    我想用Python实现HashMap 我想请求用户输入 根据他的输入 我从 HashMap 中检索一些信息 如果用户输入HashMap的某个键 我想检索相应的值 如何在 Python 中实现此功能 HashMap
  • 为什么 Double 不能隐式转换为 Decimal

    我不明白十进制和双精度的转换规则 这样做是合法的 decimal dec 10 double doub double dec 然而令我困惑的是 decimal 是 16 字节的数据类型 而 double 是 8 字节 因此将 double
  • Emma 不生成coverage.ec

    我设置了艾玛 它曾经对我有用 然后我们更改了源代码 现在它没有生成coverage ec根本不 它确实生成coverage em 测试临近结束时 出现错误消息 exec INSTRUMENTATION CODE 0 echo Downloa
  • ESP32:dsb1820 温度传感器给出恒定的负 127 读数

    我正在尝试使用连接到 esp32 微控制器的单个 dsb1820 温度传感器来获取温度读数 传感器连接到 esp32 的 GPIO 4 我打算将温度读数发送到云端 我面临的问题是温度读数总是给出值 127 我在网上某处读到 当 dsb182
  • TortoiseSVN 不要求身份验证?

    我已经在conf文件中设置了一个新的SVN存储库 运行SVNServe anon access none SVNServe 忠实地正确地做到了这一点 但是当我尝试使用 TortoiseSVN 浏览存储库时 它只是说不允许访问 它不应该要求我
  • 将 4 通道图像转换为 3 通道图像

    我正在使用 OpenCV 2 4 6 我正在尝试将 4 通道 RGB IplImage 转换为 4 通道 HSV 图像 下面是我的代码 给出错误 OpenCV 错误 未知函数断言失败 我认为 cvCvtColor 支持 3 通道图像 有没有
  • Minizinc:生成有效的转变

    希望有人能帮助我解决这个问题 最初的问题是生成有效的班次 如下所述 我有这样的数组 m m m o o l l m m m l m m m 具有固定长度 S 其中 m 是工作 o 是办公室 我自由了 我需要确保至少每 6m 就有两个 l 在
  • jQuery输入文件点击方法和IE上拒绝访问

    我尝试仅使用一个按钮作为输入文件 它在 Firefox Chrome Safari 中工作正常 但在 IE 中不行 提交表单时我总是收到 访问被拒绝 的消息 代码 input file click 有真正的解决方法吗 我在谷歌上浪费了大约2
  • 远程 Informix 11.5 命令行客户端

    Informix 11 5 是否附带了与 SQL Server 的 SQLCMD 类似的命令行工具 如果是 如何连接到远程服务器并使用它执行常规 SELECT INSERT UPDATE 查询 正如 Michal Niklas 所说 IBM
  • 如何使用 opencv.omnidir 模块对鱼眼图像进行去扭曲

    我正在尝试使用全向模块 http docs opencv org trunk db dd2 namespacecv 1 1omnidir html用于对鱼眼图像进行扭曲处理Python 我正在尝试适应这一点C 教程 http docs op
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • 使用 R 下载压缩数据文件、提取和导入数据

    EZGraphs 在 Twitter 上写道 很多在线 csv 都被压缩了 有没有办法下载 解压缩存档并使用 R 将数据加载到 data frame Rstats 我今天也尝试这样做 但最终只是手动下载 zip 文件 我尝试过类似的东西 f
  • 如何检查 NTAccount 对象代表组还是用户?

    使用返回的访问规则时 GetAccessRules True True GetType System Security Principal NTAccount 如何判断每个规则中引用的 NTAccount 对象是用户帐户还是组 Update
  • JSP/Servlet HTTP 404 错误处理

    我想在我的网络应用程序中处理 HTML 404 错误 我可以这样写
  • RMI 中的引用传递问题? [复制]

    这个问题在这里已经有答案了 有人可以告诉我我错在哪里 为什么这个 RMI 聊天应用程序不起作用 目标是通过远程对象或序列化对象实现客户端 服务器和逻辑之间的解耦 import javax swing import java awt even