I am new to Apache MINA kindly guide me how to read from IoSession. I have stored a POJO in it.
public static EchoUDPServerDiscoveryObjectResponseProperties echoProperties
session.write(echoProperties);
Custom Client:
package client;
import java.net.InetSocketAddress;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.logging.Level;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.example.udp.client.MemMonClient;
import org.apache.mina.transport.socket.nio.NioDatagramConnector;
/**
*
* #author az
*/
public class CustomClient extends IoHandlerAdapter{
private IoSession session;
private IoConnector connector;
private ConnectFuture connFuture;
public CustomClient() throws InterruptedException{
connector = new NioDatagramConnector();
connector.setHandler(this);
connFuture = connector.connect(new InetSocketAddress("192.168.3.22",6502));
connFuture.addListener(new IoFutureListener<ConnectFuture>() {
public void operationComplete(ConnectFuture future) {
if (future.isConnected()) {
session = future.getSession();
try {
try {
sendData();
// connFuture.await();
} catch (CharacterCodingException ex) {
java.util.logging.Logger.getLogger(MemMonClient.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
private void sendData() throws InterruptedException, CharacterCodingException {
IoBuffer buffer = IoBuffer.allocate(8);
buffer.setAutoExpand(true);
buffer.putString("any", Charset.forName("UTF-8").newEncoder());
buffer.flip();
session.write(buffer);
}
#Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
}
#Override
public void messageReceived(IoSession session, Object message)
throws Exception {
connFuture.getSession().getConfig().setUseReadOperation(true);
ReadFuture r = connFuture.getSession().read();
connFuture.await();
connFuture.getSession().getConfig().setUseReadOperation(true);
Object obj = r.getMessage();
System.out.println("r.getMessage(); "+obj);
IoBuffer buffer = IoBuffer.allocate(2048);
buffer.setAutoExpand(true);
Object objReceived = buffer.getObject();
System.out.println(objReceived.toString());
System.out.println("reveived Session recv...");
}
#Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("Message sent...");
}
#Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
#Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
}
#Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
#Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session opened...");
}
public static void main (String are[]){
try{
new CustomClient();
}catch(Exception ex){ex.printStackTrace();}
}
}
POJO Java
package pojo;
import java.io.Serializable;
/**
*
* #author az
*/
public class kojo implements Serializable{
private String name = "null";
private String address = "null";
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the address
*/
public String getAddress() {
return address;
}
/**
* #param address the address to set
*/
public void setAddress(String address) {
this.address = address;
}
}
Custom Server Java
package server;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
/**
*
* #author az
*/
public class CustomServer {
public CustomServer(){
try {
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
acceptor.setHandler(new ServerHandler(this));
//DefaultIoFilterChainBuilder filter = acceptor.getFilterChain();
DatagramSessionConfig dcfg = acceptor.getSessionConfig();
dcfg.setReuseAddress(true);
acceptor.bind(new InetSocketAddress(6501));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void receiveUpdate(){
}
public static void main(String are[]){
new CustomServer();
}
}
Server Handler
package server;
import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
/**
*
* #author az
*/
public class ServerHandler extends IoHandlerAdapter {
private CustomServer server;
public ServerHandler(CustomServer server) {
this.server = server;
}
#Override
public void messageReceived(IoSession session, Object message)
throws Exception {
if (message instanceof IoBuffer) {
//decode POJO and send to client
IoBuffer buffer = (IoBuffer) message;
System.out.println(buffer.getString(Charset.forName("UTF-8").newDecoder()));
buffer.setAutoExpand(true);
buffer.putObject(new pojo.POJO());
buffer.flip();
session.write(buffer);
System.out.print("Object Attached and Sent");
}
}
#Override
public void messageSent(IoSession session, Object message) {
System.out.println("Message sent");
}
#Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
#Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
}
#Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
#Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session Opened...");
}
}
Related
I have websocket server and now i need client to test its usage. I am using this clients code:
import org.msgpack.MessagePack;
import org.springframework.web.socket.BinaryMessage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class TestApp {
public static void main(String[] args) {
try {
// open websocket
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("ws://localhost:8080/websocket"));
// add listener
clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String message) {
System.out.println(message);
}
});
// send message to websocket
clientEndPoint.sendMessage(new BinaryMessage(...));
// wait 5 seconds for messages from websocket
Thread.sleep(5000);
} catch (InterruptedException ex) {
System.err.println("InterruptedException exception: " + ex.getMessage());
} catch (URISyntaxException ex) {
System.err.println("URISyntaxException exception: " + ex.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
}
import org.springframework.web.socket.BinaryMessage;
import java.net.URI;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
#ClientEndpoint
class WebsocketClientEndpoint {
Session userSession = null;
private MessageHandler messageHandler;
public WebsocketClientEndpoint(URI endpointURI) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Callback hook for Connection open events.
*
* #param userSession the userSession which is opened.
*/
#OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}
/**
* Callback hook for Connection close events.
*
* #param userSession the userSession which is getting closed.
* #param reason the reason for connection close
*/
#OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}
/**
* Callback hook for Message Events. This method will be invoked when a client send a message.
*
* #param message The text message
*/
#OnMessage
public void onMessage(String message) {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}
/**
* register message handler
*
* #param msgHandler
*/
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}
/**
* Send a message.
*
* #param message
*/
public void sendMessage(BinaryMessage message) {
this.userSession.getAsyncRemote().sendObject(message);
}
/**
* Message handler.
*
* #author Jiji_Sasidharan
*/
public static interface MessageHandler {
public void handleMessage(String message);
}
}
When i run this client, my sever accepts it, i am using spring and
void afterConnectionEstablished(WebSocketSession session)
method of BinaryWebSocketHandler fires up and everything seems fine, however after this method, the client does not set userSession , it is still null so it always throw nullpointer exception on
this.userSession.getAsyncRemote().sendObject(message);
which is weird cuz server accepts connection. What is causing this problem? Is there a fix for it?
Thanks for help!
package websocket.client;
import java.net.URI;
import javax.websocket.*;
#ClientEndpoint
public class WSClient {
private static Object waitLock = new Object();
#OnMessage
public void onMessage(String message) {
//the new USD rate arrives from the websocket server side.
System.out.println("Received msg: " + message);
}
private static void wait4TerminateSignal() {
synchronized(waitLock) {
try {
waitLock.wait();
} catch (InterruptedException e) {}
}
}
public static void main(String[] args) {
WebSocketContainer container = null; //
Session session = null;
try {
//Tyrus is plugged via ServiceLoader API. See notes above
container = ContainerProvider.getWebSocketContainer();
//WS1 is the context-root of my web.app
//ratesrv is the path given in the ServerEndPoint annotation on server implementation
session = container.connectToServer(WSClient.class, URI.create("ws://localhost:8080/WS1/ratesrv"));
wait4TerminateSignal();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null) {
try {
session.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
My chat works fine on the localhost but when I try to do it on the remote server, it doesn't go on.
RemoteClass >
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatInterface extends Remote {
public String getName() throws RemoteException;
public void sendMsg(String message) throws RemoteException;
public void setInterface (ChatInterface x) throws RemoteException; }
ClientImpl >
import Interface.ChatInterface;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ChatClient extends UnicastRemoteObject implements ChatInterface{
private String name;
private ChatInterface server;
public ChatClient(String name) throws RemoteException{
this.name = name;
}
#Override
public String getName() throws RemoteException {
return this.name;
}
#Override
public void sendMsg(String message) throws RemoteException {
System.out.println(message);
}
#Override
public void setInterface(ChatInterface server) throws RemoteException {
this.server = server;
} }
ClientMain >
import Interface.ChatInterface;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
public class Client{
public static void main(String[] args){
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
Registry registry = LocateRegistry.getRegistry("hostname", port);
ChatInterface chatClient = new ChatClient("User01");
ChatInterface chatServer = (ChatInterface) registry.lookup("ChatServer");
System.out.println("[System] Chat is ready");
chatServer.setInterface(chatClient);
String message = "["+chatClient.getName()+"] got connected";
chatServer.sendMsg(message);
Scanner s = new Scanner(System.in);
while (true) {
message = s.nextLine().trim();
message = "["+ chatClient.getName()+"]" + message;
chatServer.sendMsg(message);
}
} catch (Exception e) {
System.out.println("[System] Server failed: " + e);
System.exit(1);
}
} }
ServerImpl >
import Interface.ChatInterface;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
public class ChatServer extends UnicastRemoteObject implements ChatInterface{
private String name;
private ArrayList<ChatInterface> clients;
public ChatServer(String name)throws RemoteException{
this.name = name;
this.clients = new ArrayList<>();
}
#Override
public String getName() throws RemoteException {
return this.name;
}
#Override
public void sendMsg(String message) throws RemoteException {
broadcast(message);
}
#Override
public synchronized void setInterface(ChatInterface client) throws RemoteException {
clients.add(client);
}
public ArrayList<ChatInterface> getClients(){
return clients;
}
private void broadcast(String message) throws RemoteException {
for (ChatInterface client : clients) {
client.sendMsg(message);
}
} }
ServerMain >
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(9876);
Registry registry = LocateRegistry.getRegistry(port);
ChatServer chatServer = new ChatServer("Server");
registry.bind("ChatServer", chatServer);
System.out.println("Server ready :)");
} catch (Exception e) {
System.out.println("[System] Server failed: " + e.toString());
System.exit(1);
}
}
}
The server doesn't do anything at this line
chatServer.setInterface(chatClient);
But doesn't provoke any error. It continues to run for both client & server.
If you have any advice, thank you
I have a controller GGSNAcceptController.java:
package com.viettel.pcrf.controller;
import com.viettel.fw.Exception.LogicException;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.fw.web.controller.BaseController;
import com.viettel.pcrf.common.Const;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import com.viettel.pcrf.webconfig.service.GgsnAcceptService;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#ManagedBean(name = "ggsnAcceptController")
#Scope("view")
public class GGSNAcceptController extends BaseController implements Serializable, BaseTableCTRL {
/**
* VARIABLES & GETTER/SETTER
*/
private GgsnAcceptDTO ggsnAccept;
private GgsnAcceptDTO selectedGgsnAccept;
private List<GgsnAcceptDTO> listGgsnAccept;
public GgsnAcceptDTO getGgsnAccept() {
return ggsnAccept;
}
public void setGgsnAccept(GgsnAcceptDTO ggsnAccept) {
this.ggsnAccept = ggsnAccept;
}
public GgsnAcceptDTO getSelectedGgsnAccept() {
return selectedGgsnAccept;
}
public void setSelectedGgsnAccept(GgsnAcceptDTO selectedGgsnAccept) {
this.selectedGgsnAccept = selectedGgsnAccept;
}
public List<GgsnAcceptDTO> getListGgsnAccept() {
return listGgsnAccept;
}
public void setListGgsnAccept(List<GgsnAcceptDTO> listGgsnAccept) {
this.listGgsnAccept = listGgsnAccept;
}
/**
* SERVICE
*
*/
#Autowired
private GgsnAcceptService ggsnAcceptServ;
/**
* INIT
*
*/
#PostConstruct
#Override
public void init() {
updateCtrl();
}
#Override
public void updateCtrl() {
clear();
System.out.println(ggsnAcceptServ == null);
listGgsnAccept = ggsnAcceptServ.findAll();
}
private String ggsnAcceptSelected;
#Override
public void updateDB() {
try {
if (ggsnAccept == null) {
throw new LogicException("nullSelected", "GGSN Config is not yet selected!");
}
if (formStatus == Const.BTN_ADD && ggsnAcceptServ.isExisted(ggsnAccept)) {
throw new LogicException("insertExisted", "GGSN Config existed!");
}
// if (systemCfgSelected != null && systemCfgSelected.equals(systemCfg.getSystemCfgName()) && langServ.isExisted(systemCfg)) {
// throw new LogicException("updateExisted", "GGSN Config is existed!");
// }
BaseMessage msg = ggsnAcceptServ.updateGgsn(ggsnAccept);
if (msg.isSuccess()) {
reportSuccess("msgInfo", "Success");
}
updateCtrl();
selectedGgsnAccept = (GgsnAcceptDTO) msg.getOutputObject();
} catch (LogicException ex) {
reportError("msgInfo", ex.getDescription());
} catch (Exception ex) {
logger.error(ex, ex);
}
}
#Override
public void deleteDB() {
try {
if (ggsnAccept == null) {
throw new LogicException("nullSelected", "GGSN Config is not selected yet!");
}
BaseMessage msg = ggsnAcceptServ.deleteGgsn(ggsnAccept);
if (msg.isSuccess()) {
reportSuccess("msgInfo", "msg.delete.success");
}
updateCtrl();
} catch (LogicException ex) {
reportError("msgInfo", ex.getDescription());
} catch (Exception ex) {
logger.error(ex, ex);
}
}
#Override
public void prepareAdd() {
ggsnAccept = new GgsnAcceptDTO();
selectedGgsnAccept = null;
}
#Override
public void prepareEdit() {
if (selectedGgsnAccept != null) {
ggsnAccept = selectedGgsnAccept;
}
}
#Override
public void prepareDelete() {
if (selectedGgsnAccept != null) {
ggsnAccept = selectedGgsnAccept;
}
}
#Override
public void clear() {
selectedGgsnAccept = null;
ggsnAccept = null;
}
#Override
public void onRowChangeListener() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
An interface GgsnAcceptService.java:
package com.viettel.pcrf.webconfig.service;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import java.util.List;
public interface GgsnAcceptService {
public List<GgsnAcceptDTO> findAll();
public List<GgsnAcceptDTO> findAll(List filters);
public BaseMessage updateGgsn(GgsnAcceptDTO ggsn) throws Exception;
public BaseMessage deleteGgsn(GgsnAcceptDTO ggsn) throws Exception;
public boolean isExisted(GgsnAcceptDTO ggsn) throws Exception;
}
And a class implement above interface:
package com.viettel.pcrf.webconfig.service;
import com.viettel.fw.common.util.extjs.FilterRequest;
import com.viettel.fw.dto.BaseMessage;
import com.viettel.pcrf.webconfig.repo.GgsnAcceptRepository;
import com.viettel.pcrf.common.util.mapper.GgsnAcceptMapper;
import com.viettel.pcrf.dto.GgsnAcceptDTO;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.viettel.service.BaseServiceImpl;
import java.util.ArrayList;
#Service
public class GgsnAcceptServiceImpl extends BaseServiceImpl implements GgsnAcceptService {
private GgsnAcceptMapper mapper = new GgsnAcceptMapper();
#Autowired
private GgsnAcceptRepository repository;
public Logger logger = Logger.getLogger(GgsnAcceptService.class);
#Override
public List<GgsnAcceptDTO> findAll(List filters) {
return mapper.toDtoBean(repository.findAll(repository.toPredicate(filters)));
}
#Override
public List<GgsnAcceptDTO> findAll() {
return mapper.toDtoBean(repository.findAll());
}
#Override
public BaseMessage updateGgsn(GgsnAcceptDTO ggsn) throws Exception {
BaseMessage msg = new BaseMessage();
GgsnAcceptDTO newGgsn = mapper.toDtoBean(repository.saveAndFlush(mapper.toPersistenceBean(ggsn)));
msg.setOutputObject(newGgsn);
msg.setSuccess(true);
return msg;
}
#Override
public boolean isExisted(GgsnAcceptDTO ggsn) throws Exception {
List<FilterRequest> listReq = new ArrayList<>();
listReq.add(new FilterRequest("IP", ggsn.getIp()));
return repository.findOne(repository.toPredicate(listReq)) != null;
}
#Override
public BaseMessage deleteGgsn(GgsnAcceptDTO ggsn) throws Exception {
BaseMessage msg = new BaseMessage();
repository.delete(mapper.toPersistenceBean(ggsn));
msg.setSuccess(true);
return msg;
}
}
I got an null error when trying to access a page call controller. Is there anything wrong with my code ?
My property ggsnAcceptServ always null although i have already set autowired for it. I'm new in Spring, please help to explain why this property null. Any help would be great.
You have a problem mixing jsf and spring:
#Component
#ManagedBean(name = "ggsnAcceptController")
#Scope("view")
Your controller will be executed in jsf context not in spring context. Thats why autowiering not working.
I cannot get the client to send a message to another client without going through the server. It is an obligatory school project that should be implemented like that. I would appreciate it if someone could help me.
Server Interface:
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
public interface ChatServerInt extends Remote {
public abstract void register(ChatClientInt inClient) throws RemoteException;
public abstract ChatClientInt[] getClients() throws RemoteException;
public void disconnect(ChatClientInt client) throws RemoteException;
}
Server Implementation:
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ChatServerImp extends UnicastRemoteObject implements ChatServerInt, Runnable {
private ChatClientInt[] clientList;
int counter = 0;
private ArrayList<String> connectedClients;
/**
* List of all registered remote clients.
*/
private List<ChatClientInt> clients = null;
/**
* Construct an instance of the chat server.
*/
public ChatServerImp() throws RemoteException {
// initialise the list of client objects.
clients = new ArrayList<ChatClientInt>();
connectedClients = new ArrayList<String>();
clientList = new ChatClientInt[16];
}
/**
* Register a chat client.
*/
public void register(ChatClientInt inClient) throws RemoteException {
// perform registration.
synchronized(clients)
{
clients.add(inClient);
clientList[counter++] = inClient;
inClient = new ChatClientImp();
for(int i = 0 ; i < clients.size();i++) {
System.out.println(inClient.getName()+ "has joined\n");
}
}
}
/**After registering, each client will request the list of connected users.
* Get a list of chat clients.
*/
public synchronized ChatClientInt[] getClients() throws RemoteException {
// generate and return the list
return clientList;
}
public void disconnect(ChatClientInt client) throws RemoteException {
for(int i = 0; i < clients.size(); i++) {
System.out.println(client.getName() + "" + "has joined \n");
}
clients.remove(client);
}
/**
* Generate a random subset. Based on an implementation of D. Knuth's
* #return
*/
private static <T> List<T> randomSample2(List<T> items, int m) {
Random rnd = new Random();
for(int i=0;i<items.size();i++){
int pos = i + rnd.nextInt(items.size() - i);
T tmp = items.get(pos);
items.set(pos, items.get(i));
items.set(i, tmp);
}
return items.subList(0, m);
}
/**
* Run the server's main thread. The server should periodically
* iterate through all registered clients to find out if they
* are still alive. Any dead clients will be removed from the
* client list.
*/
public void run() {
while(true) {
//System.out.println("waiting for client connection....\n");
// sleep for a while
try {
Thread.sleep(5000);
// iterate through all the clients we know. if we can't communicate with the client
// then eliminate it else if we can communicate with the client then do nothing.
for(int i =0; i < clients.size(); i++) {
try {
if(clients.get(i).getName()==null) {
clients.remove(clients.get(i).getName());
System.out.println("Disconnected clients:\n" + clients.get(i).getName());
}
}
catch (RemoteException e) {e.printStackTrace();}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Start the chat server.
* #param args
*/
public static void main(String[] args) throws Exception {
//ChatServerInt server;
try {
String serverName = "rmi://localhost/ChatServer";
// create an instance of the chat server
//server = (ChatServerImp) new ChatServerImp();
//Launch the registry - saves invoking it manually
java.rmi.registry.LocateRegistry.createRegistry(1099);
// register the instance with the RMIRegistry
Naming.rebind(serverName, new ChatServerImp());
//Naming.rebind(serverName, server);
// create the server thread and start it
//Thread t = new Thread(server).start();
System.out.println("Server running.....\n");
}
catch(RemoteException ex) {
System.out.println("Error binding the server to rmi");
}
}
}
Message Interface:
import java.util.HashSet;
public interface MessageInt {
/**
* Add a chat recipient to the list of receivers
* #param inClient
*/
public abstract void addRecipient(ChatClientInt inClient);
/**
* Get the set of clients that have seen this message
* #return
*/
public abstract HashSet<ChatClientInt> getRecipients();
/**
* Get the message content.
* #return
*/
public abstract String getContent();
/**
* Get an ID for a sender of the message
* #return
*/
public abstract String getSource();
}
Message Implementation:
import java.io.Serializable;
import java.util.HashSet;
public class MessageImp implements MessageInt, Serializable {
/**
*
*/
private static final long serialVersionUID = -2686034785384409672L;
HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
String messageContent;
String messageSource;
public MessageImp(String inUser , String inMsg) {
messageSource = inUser;
messageContent = inMsg;
}
/**
* Add a chat recipient to the list of receivers
* #param inClient
*/
public void addRecipient(ChatClientInt inClient) {
synchronized(inClient) {
clientSet.add(inClient);
}
}
/**
* Get the set of clients that have seen this message
* #return
*/
public HashSet<ChatClientInt> getRecipients() {
return clientSet;
}
/**
* Get the message content.
* #return
*/
public String getContent() {
return messageContent;
}
/**
* Get an ID for a sender of the message
* #return
*/
public String getSource() {
return messageSource;
}
}
Client Interface:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatClientInt extends Remote {
/**
* Process a newly received message.
*
* #param inMessage
*/
public void processMessage(MessageInt inMessage)throws RemoteException;
/**
* Returns the name of the client.
*/
public String getName() throws RemoteException;
public boolean sendMessage(MessageInt inMessage) throws RemoteException;
}
Client Implementation:
import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
public class ChatClientImp extends UnicastRemoteObject implements ChatClientInt, Runnable {
/**
*
*/
private static final long serialVersionUID = 74130345076834009L;
private ArrayList <String> eventHistory = new ArrayList<String>();
private HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
private List<ChatClientInt> clients;// = new ArrayList<ChatClientInt>();
ChatClientInt[] listFromServer = new ChatClientInt[4];
String clientName;
String strMessage;
MessageInt messageObj;
ChatServerInt serverObj;
public ChatClientImp() throws RemoteException {
super();
clients = new ArrayList<ChatClientInt>();
}
public void processMessage(MessageInt inMessage) throws RemoteException {
System.out.println("message:" + inMessage.getRecipients().toString() + inMessage.getSource() + inMessage.getContent() + "\n");
}
public String getName() throws RemoteException {
return clientName;
}
public synchronized boolean sendMessage(MessageInt inMessage) throws RemoteException {
boolean success = false;
for(int i = 0; i < clients.size(); i++) {
clients.get(i).processMessage(inMessage);
inMessage.addRecipient(clients.get(i));
success = true;
}
return success;
}
public void displayMessage(String displayName, String displayMsg) {
Iterator<ChatClientInt> it = clientSet.iterator();
while(it.hasNext()) {
System.out.println(displayName + displayMsg + "\n");
}
}
public void run() {
Scanner scanner = new Scanner(System.in);
String userName = "";
try {
this.serverObj =(ChatServerInt) new ChatServerImp();
} catch (RemoteException e) {
e.printStackTrace();
}
// Keep requesting until a name is submitted that is not already used.
// checking for the existence of a name and adding the name
// is done while locking the set of names.
System.out.println("Please Enter a username\n");
while(true) {
userName = scanner.nextLine();
if(userName==null) {
return;
}
clientName = userName;
try {
serverObj.register(ChatClientImp.this);
listFromServer = serverObj.getClients();
clientSet.add(this);
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("Hi" + " " + clientName + " " + "enter your message\n");
String msg = scanner.nextLine();
if(msg.equals("exit")) {
try {
serverObj.disconnect(this);
System.exit(0);
}
catch (RemoteException e) {
e.printStackTrace();
}
}//end if
if((listFromServer.length) > 1) {
System.out.println("list from client is" + " " + listFromServer.length + "going to try to send message.....\n");
try {
this.messageObj = new MessageImp(userName, msg);
boolean result = this.sendMessage(messageObj);
if(result) {
System.out.print("sending result is:" + result + "\n");
} else {
System.out.println("sending was not successful\n");
}
} catch (RemoteException e1) {
System.out.println("Error tryiing to send message from the Run()\n");
}
} else {
System.out.println("There is no one else logged on\n");
}
}
}
public static void main(String[] args) throws RemoteException {
String serverUrl= "rmi://localhost/ChatServer";
try {
ChatServerInt server = (ChatServerInt)Naming.lookup(serverUrl);
Thread thread = new Thread(new ChatClientImp());
thread.start();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
The only way you can do that with RMI is if the clients are also RMI servers and send stubs to each other somehow.
For school we made a Java application with RMI, there are 3 applications: Server, Client and Rekenaar.
The line where it goes wrong is the Line: "test = (Range[])m.getAllRange();", it gives an dispatchUncaughtException.
package rekenaar;
import server.Opdracht;
import java.rmi.Naming;
import java.util.logging.Level;
import java.util.logging.Logger;
import interfaces.*;
import java.rmi.RemoteException;
/**
*
* #author Windows
*/
public class Rekenaar implements Runnable{
private Range range;
private IRekenCoördinator coordinator;
private long[] priemgetallen;
private Opdracht op;
private Range[] test;
public Rekenaar()
{
try{
this.coordinator = null;
this.coordinator = (IRekenCoördinator) Naming.lookup("rmi://127.0.0.1:1099/RekenC");
this.priemgetallen = coordinator.getPriemgetallen();
this.op = null;
}catch(Exception ex){ex.printStackTrace();}
}
public void Bereken()
{
try{
long rangeOndergrens = (op.getGetal()/2000) * 2000;
range = new Range(priemgetallen, rangeOndergrens);
op.setRange(range);
op.setUitkomst(range.geefSemiPriem(op.getGetal()));
coordinator.RemoveID(op.CheckRange());
IMagazijn m = op.getMagazijn();
test = (Range[])m.getAllRange();
String hoi = m.hoi();
m.AddRange(op);
}catch(RemoteException ex){ex.printStackTrace();}
}
#Override
public void run() {
KrijgtOpdracht();
}
private void KrijgtOpdracht()
{
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(Rekenaar.class.getName()).log(Level.SEVERE, null, ex);
}
if(coordinator != null)
{
try{
op = (Opdracht)coordinator.getOpdracht();
}
catch (Exception ex)
{
ex.printStackTrace();
}
if(op != null ) this.Bereken();
this.run();
}
}
}
Interface:
package interfaces;
import java.io.IOException;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
*
* #author Windows
*/
public interface IMagazijn extends Remote {
/**
*
* #param op Uitgerekende opdracht waarvan de gegevens verwerkt moeten worden op de server
* #throws IOException
*/
public String hoi() throws RemoteException;
public IRange[] getAllRange() throws RemoteException;
public void AddRange(IOpdracht op) throws RemoteException;
}
And here is the Magazijn itself which gives the IRange over RMI:
package server;
import java.rmi.RemoteException;
import java.util.ArrayList;
import interfaces.*;
import java.rmi.server.UnicastRemoteObject;
public class Magazijn extends UnicastRemoteObject implements IMagazijn{
private IRange[] ranges;
private long ondergrens;
public void setOndergrens(long ondergrens) {
this.ondergrens = ondergrens;
}
private long bovengrens;
public void setBovengrens(long bovengrens) {
this.bovengrens = bovengrens;
}
private transient MagazijnManager MM;
private transient ArrayList<Opdracht> dubbeleOpdrachten;
private transient RekenCoördinator RC;
private transient int MAGAZIJN_GROOTTE;
public Magazijn(long ondergrens, long bovengrens, MagazijnManager mm, RekenCoördinator RC)throws RemoteException
{
ranges = new IRange[(int)(bovengrens-ondergrens)/2000];
this.bovengrens = bovengrens;
this.ondergrens = ondergrens;
dubbeleOpdrachten = new ArrayList<Opdracht>();
this.MM = mm;
this.RC = RC;
MAGAZIJN_GROOTTE = (int)(bovengrens - ondergrens) + 1;
}
public void AddRange(IOpdracht op) throws RemoteException
{
ArrayList<IOpdracht> returnList = new ArrayList<IOpdracht>();
ranges[op.getRangeIndex()] = op.getRange();
returnList.add(op);
for(Opdracht o : dubbeleOpdrachten)
{
if(o.getRangeIndex() == op.getRangeIndex())
{
o.setRange(op.getRange());
o.setUitkomst(o.getRange().geefSemiPriem(o.getGetal()));
returnList.add(o);
}
}
MM.StuurOpdrachtenTerug(returnList);
}
public IRange[] getAllRange() throws RemoteException
{
return ranges;
}
public String hoi() throws RemoteException
{
return "poep";
}
public IRange getRange(int rangeIndex)
{
return ranges[rangeIndex];
}
public void StuurOpdracht(Opdracht op)
{
Opdracht o =null;
o = RC.AddOpdracht(op);
if(o!=null)
{
dubbeleOpdrachten.add(o);
}
}
public long getOndergrens()
{
return ondergrens;
}
public long getBovengrens()
{
return bovengrens;
}
public int getMagazijnGrootte()
{
return MAGAZIJN_GROOTTE;
}
}
The Rekenaar got the whole class "Range" so that is not the problem. The problem is something between the casting of IRange into Range. Range itself is Serializable and implements IRange.
The error I get: Exception in thread "main" java.lang.ClassCastException: [Linterfaces.IRange; cannot be cast to [Lrekenaar.Range;
When using RMI, you won't receive the same implementations you have on the server side. Instead you get a proxy class which will call your server. So you cannot cast your method.
Change test to a
IRange[] test
That should do it.