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?