I am trying to implement client server using ZeroMQ.
I am running a server in an infinite loop, bound to a socket and polling the the socket infinitely.
When a client sends a request, the server receives only for the first time. The subsequent requests are not received by the server, below is my code snippet
Server :
ZMQ.Socket socket = context.socket(ZMQ.REP);
socket.bind ("tcp://*:5555");
System.out.println("Server is in receive mode");
while (!Thread.currentThread ().isInterrupted ()) {
Poller poller = new Poller(1);
poller.register(socket, Poller.POLLIN);
poller.poll();
if (poller.pollin(0)) {
ZMsg zmqMessage = ZMsg.recvMsg(socket);
if (zmqMessage!=null) {
zmqMessage.getFirst().getData();
}
}
Client :
ZMQ.Socket socket = context.socket(ZMQ.REQ);
socket.connect ("tcp://localhost:5555");
ZMsg readyFrame = new ZMsg();
readyFrame.add(new ZFrame("READY"));
readyFrame.send(socket);
I tried poll out in client side like below but it did not work.
Poller poller = new Poller(1);
poller.register(socket, Poller.POLLOUT);
poller.pollout(0);
ZeroMQ is a wonderfull piece of art from Pieter HINTJENS' and Martin SUSTRIK's team. Yes, there are some low-level, technology-related issues, that still require some design efforts, nevertheless the ZeroMQ is stable and very mature.
System thinking - the toys are working as distributed automata
Yes, normal work-flow of SEQ programming languages, that work serially ( or "just"-concurrent ) suddenly gets new dimension - a distributed automata dimension.
So the local workflow is dependent on externally operated parties.
This is the case for each of the ZeroMQ Formal Communication Patterns' primitive archetypes bear human-familiar names:
one REQ-ests, second REP-lies
one PUB-lishes, anyone SUB-scribes to just listen
one PUSH-es, the other PULL-s to receive
each party, bound together in PAIR may both speak and listen, whenever, as needed
etc for BROKER, DEALER, XPUB, XSUB, et al
This is the by-design reason, why your server-side REQ-archetype behaviour will not receive any next message from any other party ( yes, there might be more clients connected to the same REQ-transport-class node ), until it indeed REP-lies ( be it an empty message or not ) to the REP-side of the distributed automata.
The best next step
Well, the best next step one may ever do in going professional in this direction is IMHO to get a bit more global view, which may sound complicated for the first few things one tries to code with ZeroMQ, but if you at least jump to the page 265 of the [Code Connected, Volume 1] [available asPdf >>> http://hintjens.wdfiles.com/local--files/main%3Afiles/cc1pe.pdf ], if it were not the case of reading step-by-step thereto.
The fastest-ever learning-curve would be to have first an un-exposed view on the Fig.60 Republishing Updates and Fig.62 HA Clone Server pair for a possible High-availability approach and then go back to the roots, elements and details.
Overheads:
As a minor note, it would be fair and resource-wise to lower the processing overheads once the Poller would be created "outside" the while(){}-loop, as there is no visible reason for reinstating such element and re-register it's services for each loop again and again:
Poller poller = new Poller(1); // new INSTANCE
poller.register( socket, Poller.POLLIN ); // pay COSTS of SETUP
// JUST ONCE, HERE
while ( !Thread.currentThread ().isInterrupted () ) {// inf LOOP
poller.poll(); // POLL !BLOCKING
if ( poller.pollin( 0 ) ) { // if ITEMS{ ... proc 'em }
ZMsg zmqMessage = ZMsg.recvMsg( socket );
if ( zmqMessage != null )
zmqMessage.getFirst().getData();
}
}
Anyway: Enjoy the worlds of distributed computing!
A REP socket must send a reply before it can receive again.
If you're just wanting a 1 way communication you might be better using a PUB & SUB.
Related
Is the code below sufficient to accept concurrent UDP transmissions? More specifically, if 2 clients transmit concurrently, will DatagramSocket queue up the transmissions and deliver them one by one as I call receive(), or will only one make it through?
DatagramSocket socket = new DatagramSocket(port, address);
byte[] buffer = new byte[8192];
while(!disconnect){
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
socket.receive(p);
}
There is no queuing by default. The client may retry till timeout or similiar are reach.
UDP is quiet fast but on heavy load you may have clients that cannot connect.
If the packets make it to your networking interface (imagine lost packets on a congested wireless channel) they will passed up and the blocking method socket.receive(p) will be called. If there is a collision of packets on the channel because of two clients transmitting at the same time you will not get any of the two packets. But this is most likely not possible because the access technology of networking interfaces will take care of this, check
CSMA/CA or CSMA/CD
After calling socket.receive(p) you should create a new thread to process the packet itself. That will make sure that the next packet can be received on the socket.
EDIT:
Description of INTEL's TX and RX descriptors
A basic solution would have on thread responsible for handling a number of incoming requests (with your desired limit) and then handing them off to other worker/request handler threads. This basic structure is very much the same with most servers: a main thread responsible for handing off requests to worker threads. When each of these worker threads is finished, the you can update a shared/global counter to let the main thread know that it can establish a new connection. This will require synchronization, but it's a neat and simple abstraction.
Here's the idea:
Server Thread:
// Receive Packet
while (true) {
serverLock.acquire();
try {
if (numberOfRequests < MAX_REQUESTS) {
packet = socket.receive();
numberOfRequests++;
requestThread(packet).run();
} else {
serverMonitor.wait(serverLock);
}
} finally {
serverLock.release();
}
}
Request Thread:
// Handle Packet
serverLock.acquire();
try {
if (numberOfRequests == MAX_REQUESTS){
numberOfRequests--;
serverMonitor.pulse();
}
} finally {
serverLock.release();
}
This is just to give you an idea of what you can start out with. But when you get the hang of it, you'll be able to make optimizations and enhancements to make sure the synchronization is all correct.
One particular enhancement, which also lends itself to limited number of requests, is something called a ThreadPool.
I've written a java intake program that send an PDF-formatted intake to a shared folder so that other people in the network can read it. However, there is not a way for the other people to know that an intake was sent unless someone tells them, so I want the program to send an alert message to the other computers telling them that an intake has been sent.
Now I've done some research into this and figured that TCP is the way to go since it's reliable. I also know that this is a one-to-many sending going on, so I assume that my Intake program will act as the server an the other computers will be the client, or should it be the other way around?
Now I assume that I have to create a client program that listens to the server and waits for it to send a message.
With that in mind, how do I:
Create a client program that listens for the message continuously until the program is closed. I assume that I'll be using "while (true)" and sleep. If so, how long do I put the program to sleep?
Make it as part of Windows service so that can load up when Windows start.
On the server end, how do I:
Send messages to more than one computer, since TCP is not capable of multicasting or broadcasting. I assume an array/vector will play a part here.
Oh, this is a one-way communication. The client doesn't have to respond back to the server.
First of all, UDP is quite reliable (in fact, as reliable as the IP protocol itself). TCP simply ensures that the data was received which involved quite a lot of magic in the back end. Unless you absolutely need to be sure that other machines got the message, you could do it with UDP. Mind that I'm not saying “Don't use TCP”, I just want to make it straight that you should take UDP into consideration as well.
Anyway, yes, you can create a simple listening program. Here is an example of a client in Java that reads messages from the server. It overrides the run method of a Thread class:
public void run() {
try {
String messageFromServer = reader.readLine();
while (messageFromServer != null) {
// Do things with messageFromServer here
// processor.processFromServer(messageFromServer);
messageFromServer = reader.readLine(); // Blocks the loop, waits for message
}
}
catch (IOException e) {
// Handle your exception
}
}
Amongst other things, my thread was set up as such:
public CommunicationThread(String hostname, int port, int timeout) throws IOException, SocketTimeoutException {
InetSocketAddress address = new InetSocketAddress(hostname, port);
socket = new Socket();
socket.connect(address, 2000); // 2000ms time out
// You can use the writer to write messages back out to the server
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
Now, regards to server-side you can do something as follows:
Write a program to allow clients to contact, given that they know your address.
Accept the connections, and store the sockets in a list.
When you need to send out a message, traverse the list and send the data to everyone on it.
You can start listening on your server with
this.socket = new ServerSocket(port);
You could (or even should(?)) make it threaded so that you can accept clients while serving others. You can accept new clients with:
socket.accept(); // Blocks, waiting for someone to connect, returns open socket
Feel free to pass that to a whole new class which can deal with BufferedWriter (and maybe even BufferedReader if you want to read from clients as well). That class is where you would implement things such as writeToClient(message)
Consider the situation where you have a ClientConnection class that has writeToClient(String s) method and (Server server, Socket socket) and initialized ArrayList conList.
Here is how you would follow:
In a separate thread in Server, accept connections with
ClientConnection con = new ClientConnection(this, socket.accept());
conList.add(con);
Then, when you want to write to clients:
for (ClientConnection c : conList) {
c.writeToClient("I'm sending you a message!");
}
I hope you get a vague idea of what you need to do. Read the Socket documentation, it's very useful. Also, as always with threaded applications, make sure you aren't doing things such as modifying a list while traversing it and avoid race conditions.
Good luck!
I have a Java TCP game server, I use java.net.ServerSocket and everything runs just fine, but recently my ISP did a some kind of an upgrade, where, if you send two packets very fast for the same TCP connexion, they close it by force.
This is why a lot of my players are disconnected randomly when there's a lot of traffic in game (when there is a lot of chance that the server will send 2 packets at same time for the same person)
Here is an example of what I mean:
If I do something like this, my ISP will close the connexion for no reason to both client and server side:
tcpOut.print("Hello.");
tcpOut.flush();
tcpOut.print("How are you?");
tcpOut.flush();
But it will work just fine if i do something like this:
tcpOut.print("Hello.");
tcpOut.flush();
Thread.sleep(200);
tcpOut.print("How are you?");
tcpOut.flush();
Or this:
tcpOut.print("Hello.");
tcpOut.print("How are you?");
tcpOut.flush();
This only started a couple of weeks ago when they (the ISP) did some changes to the service and the network. I noticed using Wireshark that you have to have at least ~150ms time between two packets for same TCP connexion or else it will close.
1)Do you guys know what is this called ? does is it even have a name ? Is it legal ?
Now I have to re-write my game server knowing that I use a method called: send(PrintWriter out, String packetData);
2)Is there any easy solution to ask java to buffer the data before it sends it to clients ? Or wait 150ms before each sending without having to rewrite the whole thing ? I did some googling but I can't find anything that deals with this problem. Any tips or information to help about this would be really appreciated, btw speed optimisation is very crucial. Thank you.
If your ISP imposes such quality of service policies and you have no way to negotiate them with it, I propose you enforce that rules on your side too with TCP/IP stack QoS configuration.
A flush marks your TCP packet as urgent (URG flag) so that it is sent whatever the buffer/TCP window state is. Now you have to tell your operating system or any network equipment on the line to either
ignore (or simply reset) the urgent flag when the previous packet has been sent in the last 150 ms and do some buffering if necessary
delay the delivery of consecutive urgent packets to honor the 150 ms constraint.
Probably an expensive software for Windows exists to do so. Personally, I think putting a Linux box as router between your Windows workstations and modem with the appropriate QoS settings in iptables and qdisc will do the trick.
You may create a Writer wrapper implementation to keep track of last flush call timestamp. A quick implementation is to add a wait call to honor the 150 ms delay between two consecutive flushes.
public class ControlledFlushWriter extends Writer {
private long enforcedDelay = 150;
private long lastFlush = 0;
private Writer delegated;
public ControlledFlushWriter(Writer writer, long flushDelay) {
this.delegated = writer:
this.enforcedDelay = flushDelay;
}
/* simple delegation for other abstract methods... */
public void flush() {
long now = System.currentTimeMillis();
if (now < lastFlush + enforcedDelay) {
try {
Thread.sleep(lastFlush + enforcedDelay - now);
} catch (InterruptedException e) {
// probably prefer to give up flushing
// instead of risking a connection reset !
return;
}
}
lastFlush = System.currentTimeMillis();
this.delegated.flush();
}
}
It now should be enough to wrap your existing PrintWriter with this ControlledFlushWriter to work-around your ISP QoS without re-writing all your application.
After all, it sounds reasonable to prevent a connection to flag any of its packet as urgent... In such a condition, it is difficult to implement a fair QoS link sharing.
My server uses data from an internal web service to construct its response, on a per request basis. I'm using Apache HttpClient 4.1 to make the requests. Each initial request will result in about 30 requests to the web service. Of these, 4 - 8 will end up with sockets stuck in CLOSE_WAIT, which never get released. Eventually these stuck sockets exceed my ulimit and my process runs out of file descriptors.
I don't want to just raise my ulimit (1024), because that will just mask the problem.
The reason I've moved to HttpClient is that java.net.HttpUrlConnection was behaving the same way.
I have tried moving to a SingleClientConnManager per request, and calling client.getConnectionManager().shutdown() on it, but sockets still end up stuck.
Should I be trying to solve this so that I end up with 0 open sockets while there are no running requests, or should I be concentrating on request persistence and pooling?
For clarity I'm including some details which may be relevant:
OS: Ubuntu 10.10
JRE: 1.6.0_22
Language: Scala 2.8
Sample code:
val cleaner = Executors.newScheduledThreadPool(1)
private val client = {
val ssl_ctx = SSLContext.getInstance("TLS")
val managers = Array[TrustManager](TrustingTrustManager)
ssl_ctx.init(null, managers, new java.security.SecureRandom())
val sslSf = new org.apache.http.conn.ssl.SSLSocketFactory(ssl_ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
val schemeRegistry = new SchemeRegistry()
schemeRegistry.register(new Scheme("https", 443, sslSf))
val connection = new ThreadSafeClientConnManager(schemeRegistry)
object clean extends Runnable{
override def run = {
connection.closeExpiredConnections
connection.closeIdleConnections(30, SECONDS)
}
}
cleaner.scheduleAtFixedRate(clean,10,10,SECONDS)
val httpClient = new DefaultHttpClient(connection)
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), new UsernamePasswordCredentials(username,password))
httpClient
}
val get = new HttpGet(uri)
val entity = client.execute(get).getEntity
val stream = entity.getContent
val justForTheExample = IOUtils.toString(stream)
stream.close()
Test: netstat -a | grep {myInternalWebServiceName} | grep CLOSE_WAIT
(Lists sockets for my process that are in CLOSE_WAIT state)
Post comment discussion:
This code now demonstrates correct usage.
One needs to pro-actively evict expired / idle connections from the connection pool, as in the blocking I/O model connections cannot react to I/O events unless they are being read from / written to. For details see
http://hc.apache.org/httpcomponents-client-dev/tutorial/html/connmgmt.html#d4e631
I've marked oleg's answer as correct, as it highlights an important usage point about HttpClient's connection pooling.
To answer my specific original question, though, which was "Should I be trying to solve for 0 unused sockets or trying to maximize pooling?"
Now that the pooling solution is in place and working correctly the application throughput has increased by about 150%. I attribute this to not having to renegotiate SSL and multiple handshakes, instead reusing persistent connections in accordance with HTTP 1.1.
It is definitely worth working to utilize pooling as intended, rather than trying to hack around with calling ThreadSafeClientConnManager.shutdown() after each request etcetera. If, on the other hand, you were calling arbitrary hosts and not reusing routes the way I am you might easily find that it becomes necessary to do that sort of hackery, as the JVM might surprise you with the long life of CLOSE_WAIT designated sockets if you're not garbage collecting very often.
I had the same issue and solved it using the suggesting found here: here. The author touches on some TCP basics:
When a TCP connection is about to close, its finalization is negotiated by both parties. Think of it as breaking a contract in a civilized manner. Both parties sign the paper and it’s all good. In geek talk, this is done via the FIN/ACK messages. Party A sends a FIN message to indicate it wants to close the socket. Party B sends an ACK saying it received the message and is considering the demand. Party B then cleans up and sends a FIN to Party A. Party A responds with the ACK and everyone walks away.
The problem comes in
when B doesn’t send its FIN. A is kinda stuck waiting for it. It has
initiated its finalization sequence and is waiting for the other party
to do the same.
He then mentions RFC 2616, 14.10 to suggest setting up an http header to solve this issue:
postMethod.addHeader("Connection", "close");
Honestly, I don't really know the implications of setting this header. But it did stop CLOSE_WAIT from happening on my unit tests.
With the advent of NIO most socket types could be "selectable" through the SelectableChannel implementation. Unfortunately the DatagramChannel does not support multicast prior to java 7. Multicast is supported in prior versions via the MulticastSocket class.
I want some way to be able to detect that there are pending messages (i.e. readable) messages on a multicast datagram socket. I would like to read until there are no remaining datagrams within the immediate time window. Having received all pending messages, then want to invoke a callback, but not individually or prior to having read all pending messages.
Making this simpler, let's assume one socket. In pseudo code:
List<Msg> received = new ArrayList<Msg>
while (true)
{
received.clear();
// initial blocking receive
data = receive_blocking (socket, datagram)
received.add (new Msg(data));
// flush out remaining messages
for (boolean receiving = true ; receiving ; )
{
// non-blocking
if (receive_nonblocking (socket, datagram))
received.add (new Msg(datagram));
else
receiving = false;
}
callback (received);
}
The question is how to implement receive_nonblocking without NIO 2. I do not need the Selector mechanism, but wondering whether there is some way I can do a non-blocking read(s) or otherwise detect whether there is something pending.
I had read that to use the selector, the channels must be created directly as in new DatagramChannel(), rather than acquiring a channel after socket creation. So if am correct, could not use the socket.getChannel() to create a selector post socket creation.
Is there any way to do this that doesn't involve JNI or timers, pre java 7?
Just set a very short read timeout, and catch SocketTimeoutException, which will be thrown when it expires, and break out of your reading loop.