I am developing a TCPIP application where the client will send information to a specified port and the server will listen to that port. I would like to achieve the following:
Reconnect to the the client/port to see whether it is active after a specified time period.
I have the below code implemented:
#Stateless
#Local
public Listener implements ConnectionListener {
public void listen() throws Exception {
ServerSocket serverSocket = new ServerSocket(somePort);
Socket socket = serverSocket.accept();
while(!socket.isClosed()) {
}
}
}
public interface ConnectionListener {
public void listen() throws Exception;
}
How can this be achived with EJB technology? I know the while loop is wrong but what can be included. I have two approaches:
Wait for a time period to reconnect
Thread
However, I do not wish to use the Thread appraoch.
I know in EJB there are things such as an EJBTimer. What would be the best way to implement this and how could this be implemented in the code. Could you help how I could change the while loop to do what I want it to do?
Also, the client has no API to call on this application. How can this instance be triggered on start up of the Application Server so that messages are listened to. Usually, this could be achieved through a Servlet but I don't think this will work. Any ideas?
This kind of functionality is at the "edge" of the types of things you would do in EJB. typically, EJBs do not directly do network type activity, especially long term listening.
what you really want is an EJB singleton. this is kind of like a standalone instance which can do more advanced things like custom concurrency/threading and (relevant to you) start a custom socket listener.
Related
I want to able to have a client/server application which can perform the following:
Have client send "java task instructions" (ex. name of method, class to run or app to execute) to a remote server
server receives the task execution details and launches a new JVM and loads the classpath etc...
server executes the task
server stores the task response in a cache
shuts down the new JVM
server continues to wait for further executable task details which could reference object in cache by name
What is the best APIs to implement this in Java if I don't want to use RMI?
Do I want to establish a connection by using a socket or is there an easier API?
From what I know, correct me if im wrong, I cannot use ProcessBuilder to execute a static method or to get a response.
thanks in advance
UPDATE
I am new to threads and RMI, so how would I then make it so that when client gets the factory stub to creates a new object which will contain the behavior actually needed to execute a task on the server, that the object code is executing in its own thread?
I want this behavior so that two different clients are executing two different tasks at the same time in different threads without reusing the same remote object instance. Here is some simple sample code to help explain what I want
Factor Interface
public interface Factory extends Remote
{
public Executor create() throws RemoteException;
}
Factory implementation
public class FactoryImpl implements Factory
{
public FactoryImpl()
{}
#Override
public Executor create() throws RemoteException
{
//create a new executor in another thread
}
}
Executor interface
public interface Executor extends Runnable, Remote
{
public String executeTask(String pClass, String pMethod, List<String> arguments) throws RemoteException;
}
Do I just want to create/start a new Runnable class that instantiates the executor object?
I'm making a html5/js game that will have online capabilities for my backend I've decided to use a wildfly server. The client will communicate with the server via web sockets.
I intended for my wildfly server to also be in charge of game logic decisions such as moving npc's. My plan was to have a #startup bean that would run a server game loop to handle this logic. The server loop would then talk to the serverEndPoint via HornetQ. My serverEndPoint and server loop look like this:
ServerEndPoint
#ServerEndpoint(value= "/game/{user-id}")
public class GameEndpoint {
#Inject
GameManager gameState;
GameWorld gameWorld;
Player p;
private Logger logger = Logger.getLogger(this.getClass().getName());
#OnOpen
public void onOpen(Session session){
//do stuff
}
#OnMessage
public void onMessage(Session session, String message){
//do stuff
}
#OnClose
public void onClose(CloseReason reason){
//do stuff
}
#OnError
public void error(Throwable t){
//do stuff
}
}
GameWorld
#Startup
#Singleton
public class GameWorld {
#Inject
GameManager gameState;
private Logger logger = Logger.getLogger(this.getClass().getName());
#PostConstruct
public void init(){
gameloop();
}
private void gameloop(){
while(true){
logger.info("This is a test!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#PreDestroy
public void terminate(){
//do stuff
}
}
the issue with this is that the server loop freezes everything as it is a infinite loop(for instance if I try and access the html web page I get a 404). obviously this could be solved if the serverLoop was on its own seperate thread but after doing some research it seems threading in jboss is very difficult as its hard to know what dependencies to inject e.t.c
Can anyone shed some light on how I can solve this issue? any help on the matter would be amazing.
What you have encountered has to do with what Java EE is and what it not is: Java EE is optimized for handling many concurrent, short-lived requests, each of which (usually) handle a single transaction. The containers do that very well, particularly with stateless beans, but also with stateful beans (cluster replication etc). As such, Java EE might be well-suited to process the requests coming from your HTML5/JS clients and feed the requests to the messaging infrastructure. Java EE is not, however, designed for long running, thread-blocking background processes like yours.
FWIW: Another issue that you have not yet encountered is, even if you could get that one fixed: Next you'll encounter the transaction timeout on your #PostConstruct method.
I think you are better of with moving the game engine out of the Java EE stack. You already mentioned you plan to use HornetQ - then why not put the game engine in a simple standalone application that receives messages from HornetQ and feeds replies back into HornetQ.
Another option might be a dedicated Java game server engine, see, e.g., this question and its accepted answer on programmers.stackoverflow.com. (Update: it seems the "RedDwarf Server" project mentioned in that answer was discontinued 3 years ago).
If you absolutely want to use the Java EE environment, I suggest you use a TimerService instead. Note, however, that this also requires that your game loop calculation is quick and guaranteed to finish until the next timeout is scheduled, otherwise the container will skip the scheduled invocation (with a "still running" message or similar).
Finally, let me mention that if I were to start a new game server today, I would definitely take a look at Akka, Node.js or similar projects that support "reactive" programming.
I am new to RMI and springs and need a little help with a feature we are implementing.
We are creating chat software with java and want to use RMI with springs.
I can setup a client server interaction fairly easily using RMIServerExporter, interfaces, etc.
The problem I can get my head around is that the client needs to pool data from the server. We need to get keep checking for new messages.
We can't push data from the server for other reasons.
How do I go about setting up RMI with springs so that the client pools data from the server. I have looked up callbacks but this involved pushing from the server!?
Is there away to do this. Let me know if you need to me explain this further
RMI is just a transport protocol used for client-server communication. On client side, once your RmiProxyFactoryBean has been properly defined and initialized in Spring container, where, when and how to use this service bean is totally up to developer. For a server pooling implementation, we usually use ScheduledThreadPoolExecutor to schedule the RMI call in a given time interval, for example:
public class ChatClient {
// Defined and wired as RmiProxyFactoryBean in applicationContext.xml
private ChatService chatService;
private ScheduledExecutorService scheduleTaskService;
... ...
// At some point during chat application running life cyle:
scheduleTaskService = Executors.newScheduledThreadPool(5);
// This schedule pooling task to run every 2 minutes:
scheduleTaskService.scheduleAtFixedRate(new Runnable() {
public void run() {
// Pooling server using RMI call:
chatService.poolingData();
}
}, 0, 2, TimeUnit.MINUTES);
... ...
}
For a more enterprise solution, we usually use Quartz, check out this blog post as a live example.
I'm developing a application using Java RMI which enable clients to register topics they want to listen (zero or more) and topic (zero or one) they want to speak about. There is a central server which offers registration service. The communication of clients avoids server with the exception of initial registering of ListenerCallback or SpeakerCallback.
Clients and server work according to Observer pattern.
Callback interfaces:
public interface ListenerCallback extends Remote{
void notify(String topic, String msg) throws RemoteException;
}
public interface SpeakerCallback extends Remote{
Unregister accept(ListenerCallback listenerCallback) throws RemoteException;
}
Fragment of registration method on server, both speaker and listener are remote references:
for (SpeakerCallback speaker : registeredSpeakers){
try {
speaker.accept(listener);
} catch (RemoteException e){
//TODO should I unregister speaker?
}
}
As written above in //TODO, I suppose I should unregister speaker from my application registries, because as far as I know RemoteException indicates that the connection with client is broken.
The problem I'm struggling with is how should I manage abnormal client shutdown that only listen to some topic but speak about none. The server holds them in application registries, but has no way to determine whether they are still valid, because it doesn't call its notify() method.
Shoud I add some bogus method to ListenerCallback interface just for trying to determine whether client is still reachable?
Or should I implemented a protocol which would enable clients who speak about (these call notify() method) a certain topic notify server that some listening clients are no more available?
This is a job for the Remote Session pattern. Every client does a login step, which allocates and returns a new remote object which is really a session object, which in turn:
has a logout() method, which unexports the object
provides the other APIs the client needs, and
implements Unreferenced, with the unreferenced() method calling logout().
So if the client either calls logout() or dies the object will disappear; and whatever collateral actions need to happen can all happen in the logout() method.
If you get a remoteException, that does not mean the client is down, you will have to check the sub types of remoteEception like ConnectException etc which inform that there is no endpoint anymore, only then you can unregister the client.
For checking if the clients are alive you can implement some dummy API on the client side and use it for pinging the client in a timer task. You can optimize this ping interval based on the severity of the client registration's staleness.
We have a Java listener that reads text messages off of a queue in JBossMQ. If we have to reboot JBoss, the listener will not reconnect and start reading messages again. We just get messages in the listener's log file every 2 minutes saying it can't connect. Is there something we're not setting in our code or in JBossMQ? I'm new to JMS so any help will be greatly appreciated. Thanks.
You should implement in your client code javax.jms.ExceptionListener. You will need a method called onException. When the client's connection is lost, you should get a JMSException, and this method will be called automatically. The only thing you have to look out for is if you are intentionally disconnecting from JBossMQ-- that will also throw an exception.
Some code might look like this:
public void onException (JMSException jsme)
{
if (!closeRequested)
{
this.disconnect();
this.establishConnection(connectionProps, queueName, uname, pword, clientID, messageSelector);
}
else
{
//Client requested close so do not try to reconnect
}
}
In your "establishConnection" code, you would then implement a while(!initialized) construct that contains a try/catch inside of it. Until you are sure you have connected and subscribed properly, stay inside the while loop catching all JMS/Naming/etc. exceptions.
We've used this method for years with JBossMQ and it works great. We have never had a problem with our JMS clients not reconnecting after bouncing JBossMQ or losing our network connection.
I'd highly recommend you use the Spring abstractions for JMS such as the MessageListenerContainer to deal with reconnection, transactions and pooling for you. You just need to supply a MessageListener and configure the MessageListenerContainer with the ConnectionFactory and the container does the rest.
If you're purely a listener and do no other JMS calls other than connection setup, then the "onException() handler" answer is correct.
If you do any JMS calls in your code, just using onException() callback isn't sufficient. Problems are relayed from the JMS provider to the app either via an exception on a JMS method call or through the onException() callback. Not both.
So if you call any JMS methods from your code, you'll also want to invoke that reconnection logic if you get any exceptions on those calls.
Piece of advice from personal experience. Upgrade to JBoss Messaging. I've seen it in production for 4 months without problems. It has fully transparent failover - amongst many other features.
Also, if you do go with Spring, be very careful with the JmsTemplate.