RMI如何实现轮询机制?

Posted

技术标签:

【中文标题】RMI如何实现轮询机制?【英文标题】:How Polling mechanism can be realized with RMI? 【发布时间】:2010-10-02 15:42:28 【问题描述】:

按照我为具有 RMI 服务器回调的多用户/网络回合制游戏创建的设计/架构,我尝试创建一个分布式动画,其中我的模型(球)是远程对象,它通过来自的回调机制更新客户端服务器。

目前的代码情况是:

模型远程对象,正在迭代客户端列表并调用它们的更新方法,

public class BallImpl extends UnicastRemoteObject implements Ball,Runnable 


    private List<ICallback> clients = new ArrayList<ICallback>();


    protected static ServerServices chatServer;
    static ServerServices si;

    BallImpl() throws RemoteException 
        super();

 ....

    public  synchronized void move() throws RemoteException 
        loc.translate((int) changeInX, (int) changeInY);
    

    public void start() throws RemoteException 
        if (gameThread.isAlive()==false )
            if (run==false)
                  gameThread.start();

            
    
    /** Start the ball bouncing. */

        // Run the game logic in its own thread.

            public void run() 

                while (true) 
                    run=true;
                    // Execute one game step
                    try 
                        updateClients();
                     catch (RemoteException e) 
                        e.printStackTrace();
                    

                    try 
                        Thread.sleep(50);
                     catch (InterruptedException ex) 
                    
                
            
     public void updateClients() throws RemoteException 

        si = new ServerServicesImpl();
        List<ICallback> j = si.getClientNames();
        System.out.println("in messimpl " + j.size());
        if (j != null) 
            System.out.println("in ballimpl" + j.size());
            for (ICallback aClient : j) 
                aClient.updateClients(this);
            

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

正在实现回调接口并有更新方法实现的客户端:

public final class thenewBallWhatIwant implements Runnable, ICallback 

.....

@Override
public void updateClients(final Ball ball) throws RemoteException 

    try 
        ball.move();
        try 
            Thread.sleep(50);
         catch (Exception e) 
            System.exit(0);
        
     catch (Exception e) 
        System.out.println("Exception: " + e);
    

 .....

我的普遍看法是我正在使用 RMI 实现推送机制,在这种情况下我需要实现轮询)

如果是这种情况,我该如何使用 RMI 实现轮询机制?

感谢您的任何反馈。

吉比拉拉

【问题讨论】:

【参考方案1】:

轮询独立于您用于实现客户端和服务器的协议。

客户端通过无限循环进行轮询。在循环内部,有一个向服务器请求信息的请求。服务器发送回所需的信息或“未准备好”消息。客户端做它的事情并等待直到需要发送下一个请求。

如果您碰巧选择了 RMI,则意味着 RMI 客户端和服务器。但是轮询机制是一样的。

将问题分解成小块 - 这样会更容易思考和解决。

忘记轮询开始吧。你能写一个 RMI 服务器,启动它,然后创建一个单独的客户端来发出一个请求吗?如果你能做到这一点,那么你把它放在一个带有睡眠的循环中来实现延迟,你就完成了。

【讨论】:

谢谢,我粘贴了代码以便更好地了解我在做什么 这里发生的事情太多了。简化 - 你能做我建议的简单事情吗?没有 UI,没有线程 - 只需创建服务器、创建客户端并建立连接。从服务器的接口开始,因为它表示客户端希望从服务器返回什么以及服务器需要传递什么。我不会读你的代码。我给了你一张很好的照片。现在由您决定。 谢谢,但我认为您正在谈论使用 RMI 实现客户端和服务器通信,并且我认为我已经超出了那个阶段,正如我已经提到的那样,我有这个基于回调的设计,它也成功了基于游戏,但我现在在这种动画情况下遇到问题,当多个客户端执行重复移动的相同方法时,我希望当该移动方法已经被一个客户端调用时,其他客户端不需要调用该方法导致球移动得越来越快。 "如何用 RMI 实现轮询机制?" - 这就是我要回答的问题。 我的意思是你所说的我几乎要这样做,如果不是那么我在遵循你给出的想法时哪里错了,这就是我展示代码的原因。【参考方案2】:

我不相信您可以通过 Java RMI 实现回调。您需要按照您的建议设置轮询,或者让您的“客户端”RMI 服务器可以直接向它们发送消息。

你怎么能以不同的方式做到这一点?我建议使用 JMS 消息将命令对象发送到客户端,这将为您处理所有分发。

【讨论】:

谢谢,但是当这不是 RMI 回调时,您将如何看待上面的内容。除了 RMI,我别无选择。 当您将对象作为参数传递时,它会在客户端序列化并在服务器上反序列化。创建该对象的副本。如果您在副本上调用方法,它们许多似乎都可以工作,但它们不会调用原始方法。我已经实现了这个回调将反向代理返回给客户端的系统(使用我编写的自定义 RMI),但我从未见过使用标准 RMI 进行这项工作。 我想到了你所指的问题;我遇到了这个问题我创建了一个序列化对象(球),我正在调用它的方法,但有些方法似乎不起作用,我有 4 个球和我设置的颜色和半径不同,但是所有球的半径和颜色都与第一个球相同,我不知道为什么会出现这个问题,也不知道问题是否来了,因为你谈到的问题。什么是自定义 RMI,如果你可以谈论,我创建了一个应用程序,现在想要优化它和通用模型/模板,但我担心我讨论的问题。 您希望完成多少工作?当您必须从 RMI 应用程序中提取/制作非常简单的网络库/API 以进行小型实时游戏/模拟时,我创建了一个应用程序,但它没有实现这个目标吗?。 使用调试器调试程序时会看到什么。这应该准确地向您展示每一行对什么对象发生了什么。顺便说一句,在不报告错误或异常的情况下调用系统退出是一个非常糟糕的主意。这意味着您的应用程序可能会死掉,而您不知道/指出原因。

以上是关于RMI如何实现轮询机制?的主要内容,如果未能解决你的问题,请参考以下文章

Java的RMI远程方法调用实现和应用

简单轮询结果文件的实现

libevent 的实现细节是啥?轮询机制的封装?

OSChinaclient源代码学习--轮询机制的实现

RMI的概念

Keepalived 之 双主模式+DNS轮询机制 实现高负载