Java RPC - Notifica al client senza chiamata al metodo sul lato client

0

Il progetto corrente è un'applicazione web java di base scritta con il pattern RPC e java ObjectStream ...

Ecco alcune classi base usate dal mio framework di base:

public abstract class AbstractServer implements Runnable
{
    protected int port;
    protected AbstractController controller;

    public AbstractServer(int port, Class <? extends AbstractController> controller) throws IllegalAccessException,
            InstantiationException
    {
        this.port = port;
        this.controller = controller.newInstance();
    }

    public AbstractServer(int port, AbstractController controller)
    {
        this.port = port;
        this.controller = controller;
    }

    @Override public void run()
    {
        ExecutorService pool = Executors.newCachedThreadPool();

        try(ServerSocket socket = new ServerSocket(this.port))
        {
            while(!Thread.currentThread().isInterrupted())
            {
                this.controller.call(socket.accept(), pool);
            }
        }
        catch(IOException exc)
        {
            exc.printStackTrace();
        }
    }
}

public abstract class AbstractController
{
    public void call(Socket socket, ExecutorService pool)
    {
        pool.execute(new Runnable()
        {
            @Override public void run()
            {
                try
                {
                    AbstractController.this.control(socket);

                    if(null != socket)
                    {
                        socket.close();
                    }
                }
                catch(IOException exc)
                {
                    throw new InternalError(exc);
                }
            }
        });
    }

    public abstract <T extends Exception> void control(Socket socket) throws T;
}

Ora la mia classe principale, un server RPC di base:

public class RPCServer extends AbstractServer
{
    public RPCServer(int port, Class <?> service) throws Exception
    {
        super(port, new RPCController(service.newInstance()));
    }

    protected static class RPCController extends AbstractController
    {
        protected Object service;

        public RPCController(Object service)
        {
            this.service = service;
        }

        @Override public void control(Socket socket)
        {
            try (ObjectInputStream sin = new ObjectInputStream(socket.getInputStream());
                    ObjectOutputStream sout = new ObjectOutputStream(socket.getOutputStream()))
            {
                Object object;
                String name = (String) sin.readObject();
                Object [] params = (Object[]) sin.readObject();

                try
                {
                    Class <?> [] paramTypes = null;

                    if(null != params)
                    {
                        paramTypes = new Class[params.length];

                        for(int index = 0; index < params.length; ++index)
                        {
                            paramTypes[index] = params[index].getClass();
                        }
                    }

                    Method method = this.service.getClass().getMethod(name, paramTypes);
                    object = method.invoke(this.service, params);
                }
                catch(InvocationTargetException exc)
                {
                    object = exc.getTargetException();
                }
                catch(Exception exc)
                {
                    object = exc;
                }

                sout.writeObject(object);
                sout.flush();
            }
            catch(Exception exc)
            {
                exc.printStackTrace();
            }
        }
    }
}

La classe interna RPCController è responsabile della gestione delle richieste RPC in arrivo e dell'esecuzione del metodo specificato ... Qui l'implementazione di una delle mie classi client di base:

public class RPCClient
{
    protected InetAddress address;
    protected int port;

    public RPCClient(InetAddress address, int port)
    {
        this.address = address;
        this.port = port;
    }

    public Object call(String name, Object [] params) throws Exception
    {
        try(Socket socket = new Socket(this.address, this.port);
                ObjectOutputStream sout = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream sin = new ObjectInputStream(socket.getInputStream()))
        {
            sout.writeObject(name);
            sout.writeObject(params);
            sout.flush();

            Object object = sin.readObject();

            if(object instanceof Exception)
            {
                throw (Exception) object;
            }

            return object;
        }
    }
}

Ho già eseguito con successo l'applicazione Web, ma la mia domanda effettiva è: come posso notificare al client i messaggi già arrivati, rispettivamente gli eventi lato server / la trasmissione di dati lato server al client? C'è un modo per chiamare il metodo del client sul lato server o per registrare un gestore di messaggi client sul lato server, per rendere possibile informare il cliente delle modifiche?

Forse il concetto è una connessione unidirezionale o devo implementare funzionalità aggiuntive? Come posso risolvere questo problema?

    
posta 0x1C1B 05.08.2018 - 19:39
fonte

0 risposte

Leggi altre domande sui tag