So I've made a client/server pair in Java using RMI. The point is to send messages from the client to the server and print out how many messages we've received and how many we've lost (im comparing it to UDP so dont ask why I'm expecting to lose any with RMI).
So anyway, written the code, everything seems to work fine, I bind to the server and send the messages, the server receives them all and outputs the results.
Only problem is, after I've sent the last message from the client it throws a RemoteException and I have no idea why.
My only guess is that the server has shut down fist so its letting me know I can't contact the server any more (ie my iRMIServer variable is now invalid).
Funny thing is I thought that the client would shut down first because it terminates after sending the messages. The reason it might not be shutting down first is because it has to wait for a reply (ACK) from the server to confirm receipt of the message??
Maybe in this overlap time of the server replying to let us know everything is ok, the server shuts down and we can't connect to it again.
The code for sending the messages at the client end is as follows:
try {
iRMIServer = (RMIServerI) Naming.lookup(urlServer);
// Attempt to send messages the specified number of times
for(int i = 0; i < numMessages; i++) {
MessageInfo msg = new MessageInfo(numMessages,i);
iRMIServer.receiveMessage(msg);
}
} catch (MalformedURLException e) {
System.out.println("Errpr: Malformed hostname.");
} catch (RemoteException e) {
System.out.println("Error: Remote Exception.");
} catch (NotBoundException e) {
System.out.println("Error: Not Bound Exception.");
}
So it is sending the messages from 0-999 if I select 1000 messages to be sent.
After printing out the results from the server I call System.exit() straight away which could cause it to terminate early without waiting for the appropriate responses from the client?
If you can help I'd be greatly appreciative, and if you need any more info I'd be happy to provide.
Thanks in advance.
You can't shutdown the server in the middle of a remote method. The server has to send back an OK or exception status, or a return value if the method has one, and that's what your client is failing on when trying to receive. You have to schedule the shutdown to execute a bit later.
Related
I am trying to send PongMessage to a server from web-socket client (heart-beat message you may say).
In server, I have written a method like this inside a class Annotated with #ServerEndpoint :
#OnMessage
public void onPong(PongMessage pongMessage, Session session) {
LOGGER.log(Level.INFO, " -- Got Hit Yaay!! -- ");
try {
session.getBasicRemote().sendText(PONG_RECEIVED);
} catch (IOException e) {
e.printStackTrace();
}
}
PongMessage Accepts ByteBuffer according to an oracle documentation. I tried generating a bytebuffer in server and sending exact same generated bytebuffer value from socket client. Server still throws an exception saying it Cannot decode a string.
I am not able to hit onPong() method. Is there any format for pongmessage that client can send to a websocket server so that onPong() method gets invoked? What am I doing wrong here? Any Ideas ?
I have found an old post that Ping/Pong messages should be handled by the browser. If that is still true (i'm not sure), then you should be moving to a "custom" solution: don't use PongMessage. Receive some JSON defined by you.
I'm using Qpid Proton (proton-j-0.13.0) to send messages over AMQP to an ActiveMQ 5.12.0 queue. On a development machine, where ActiveMQ and the Java program run on the same machine, this is working fine. On a test environment, where ActiveMQ is running on a separate server, we see the send() method hangs in 15 to 20 percent of the cases. The CPU also remains around 100% when the send() method hangt. When the send() succeeds, it completes within 0.1 seconds.
Statements to perform a send are similar to this:
final Messenger messenger = Messenger.Factory.create();
messenger.start;
messenger.put(message); // one message of 1 KByte
messenger.send(1);
messenger.stop();
I'm aware Messenger.send(int n) is a blocking method. However, I don't know why it would block my calls. I can add a timeout and try to resend the message, but that's a workaround instead of a proper solution.
Statements to receive the sent messages from ActiveMQ are similar to this:
this.messenger = Messenger.Factory.create();
this.messenger.start();
this.messenger.subscribe(this.address);
while (this.isRunning) {
try {
this.messenger.recv(1);
while (this.messenger.incoming() > 0) {
final Message message = this.messenger.get();
this.messageListener.onMessage(message);
} catch (final Exception e) {
LOGGER.error("Exception while receiving messages", e);
}
}
Am I missing something simple, being a Qpid newbie? Could this be configuration in ActiveMQ? Is it normal to add a timeout and retry? Any help to resolve this would appreciated.
How can I disconnect a netty client from the server so it executes the handerRemoved method on the server side and completely stops running? I tried using group.shutDownGraceFully() but the client still keeps connected to the server. Is there any method I am missing?
I also noticed when I try to connect to the server and it is not reachable (connection refused), the next time I connect to a real server it connects but it does not send or get any more messages.
you seem to be new to network programming in general.
I am new to netty so please don't take anything I say as 100% true and especially not anywhere near 100% efficient.
so one major basic fact of network programming is that the the client and server are not directly linked (obviously). In order to execute a method on the server, you will need to send a message from the client to the server. for instance:
what you have on Client:
//on shutdown
{
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
what you want:
{
yourchannelname.writeAndFlush("bye"+"\r\n")
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
and when the server receives the bye command:
// If user typed the 'bye' command, wait until the server closes
// the connection.
if ("bye".equals(line.toLowerCase())) {
ch.closeFuture().sync();
break;
}
}
//this is for safety reasons, it is optional-ish
// Wait until all messages are flushed before closing the channel.
if (lastWriteFuture != null) {
lastWriteFuture.sync();
}
//what you already have
} finally {
// The connection is closed automatically on shutdown.
group.shutdownGracefully();
}
}
hope this helped, iv never answered a question on stack overflow before so I hope I at least sound like I know what im doing :P
I am getting started with the Finagle library in Java and trying to bring up couple of basic HTTP services which communicate in JSON.
Let this be master and slave services.
Master service has the following logic:
It runs a thread on start up which sends command requests to the slave
It listens for error/success reports from slave
The slave server's logic is this:
For the command it received, it immediately sends an ack.
Then it starts a thread to perform a task specified by the command.
It sends the result of the job (or error) back to master in JSON.
I have the following code:
HttpMuxer muxService = new HttpMuxer().withHandler("/", new MasterService());
ListeningServer server = Http.serve(new InetSocketAddress("localhost", 8000), muxService);
// This method runs a Function0 closure in a Future pool.
// It sends requests to slave, and exits after the commands are sent.
sendCommands();
try {
Await.ready(server);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
My question is this:
Now, ideally the job could take a few seconds to complete. But in case of errors, it could almost immediately send a message to master with error report. Once I call sendCommands(), any moment I can expect the slave to attempt contacting the master.
Is the server up and listening with just the call to Http.serve()? Or does this happen in the Await.ready() call?
I am assuming the latter, and putting a Thread.sleep() in the thread spawned by sendCommands(). Is this required?
Also, is there an altogether better way to cleanly start this command issuing thread at the master?
Okay I figured this out after some testing.
The call to Http.serve() starts the server on the given port, the incoming requests are correctly handled by the MasterService
The Await.ready() loop just keeps the thread alive. The server will respond even if you replace this with a Thread.sleep(n)
I want to create simple download accelerator.
How it works
Server wait for incoming connection.
Client connect to server.
Then, server send file size to client and wait for download connection.
Client got file size, then create download thread and these thread are connect to server.
After server got connection from each thread, server will wait for start and end offset file from thread.
Each thread send start and end offset file to server.
After server got offsets, server will send the portion of file to thread.
Each thread will read and write to file. For example, buffer.p01, buffer.p02, buffer.p03
Client merge all file into one file order by sequence. ( Not yet implemented )
I think server side it works correctly but client side it has some problem.
The problem is if I set MAXTHREAD to 1, it works correctly. But if I set more than one, it stuck somewhere forever.
This is server side code..
http://pastebin.com/TEakGB0c
and this is client side code with multithreading
http://pastebin.com/wKhP7DxS
Thanks your.
You have a pretty big obvious problem. ServerSocket's accept method returns a new socket every time. In your server code here
initSocket = servSock.accept();
initSocket is a class member field which means you will over write the old socket and never close it. You should start a new thread to handle this socket and from what I see it looks like you just keep reusing the same socket. That won't work. Look at tutorials on how to open sockets. Sorry I can't help more but there is a lot of things going on here that just won't work. Maybe you can start focusing on part of the code and we can help more.
I agree, it could be a small issue or it could be a big one, some example code would help us aid you, If you try to connect to a server 3 times using the same port you will get an error because you can only have 1 connection per port, the problem could be super simple or very complex, if you edit your post and add your code then we can better help you.
Please close your OutputStream os
Sending u a snippet
public static boolean sendFile() {
int start = Integer.parseInt(startAndEnd[0]) - 1;
int end = Integer.parseInt(startAndEnd[1]) - 1;
int size = (end - start) + 1;
try {
os = initSocket.getOutputStream();
os.write(byteArr, start, size);
os.flush();
System.out.println("Send file to : " + initSocket);
} catch (IOException e) {
System.out.println(e.getLocalizedMessage());
disconnected();
return false;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ex) {
Logger.getLogger(FileServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return true;
}