Search code examples
javaserverzeromqjzmqjeromq

ZeroMQ running server Java


Im currently trying to develop a server that should basically get incoming data from unknown number of clients at any time. I.e the system will have multiple clients to send data and the servers job is basically to just collect the data and save it to a database.

  1. Now I want the server to be running continuously. Right now the server just receive one client and shuts down. If i say do an while(true)- loop surrounding the receive and print message part, It doesn't even do it once.

  2. As i might understand REP REQ is not the best pattern for this, what pattern would be the best to just have the server getting incoming data?

  3. Using Curve (a.k.a. Ironhouse pattern), the client needs to have the servers certificate, how should lets say a new client that wants to send data to the server, have access to the servers certificate? All examples I've found from the ZMQ Guide or other sites just refer to a local, often same class, server-client application where the client just access the certificate since they're in the same class... But that's not a realistic case.

Appreciate all answers, tips and suggestions. Thanks.

private class ServerTask extends Thread {

        public void run() {

            try(ZContext context = new ZContext()){ //create context
                ZAuth authenticator = new ZAuth(context); //create authenticator for incoming clients
                authenticator.setVerbose(true); //get indication of what the authenticator is deciding
                authenticator.allow("127.0.0.1"); //Whitelisting an adress, all other adresses will be rejected
                //authenticator.configureCurve(CERTIFICATE_FOLDER); //Tell authenticator to use the certificate store in .curve
                //ZCert server_cert = new ZCert(); //Create a server certificate
                //writeServerCertToFile(server_cert); //write the cert so client can use it

                //Create and bind server socket
                ZMQ.Socket server = context.createSocket(SocketType.REP);
                //server.setZAPDomain("global".getBytes());
                //server.setCurveServer(true);
                //server.setCurvePublicKey(server_cert.getPublicKey());
                //server.setCurveSecretKey(server_cert.getSecretKey());
                server.bind("tcp://*:9000");

                //recieve and print message

                String message = server.recvStr(0);
                System.out.println("received message: " + message);
                System.out.println("I should not be printed before the recieved message");



                try {
                    System.out.println("destroys the auth and context");
                    authenticator.close();
                    context.destroy();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        }
    }

Solution

  • I solved this months ago but if will help someone using ZeroMQ in the future, I ended up using the pull-push pattern with loadbalancing the data to a threadpool of workers. Also using Inproc for frontend/backend communication. That seemed to be the best fit solution.