1
\$\begingroup\$

The usual way is to implement socket server to handle concurrent requests by creating new thread for each request.

Instead of this approach i tried to create a server using consumer-producer design, as follows.

Main thread

//holds socket instances
ConcurrentLinkedQueue<Socket> queue = new ConcurrentLinkedQueue<>();

//create producer thread
Thread producer = new Thread(new RequestProducer(queue));
//create consumer thread
Thread consumer = new Thread(new RequestConsumer(queue));

producer.start();
consumer.start();

RequestProducer thread

//this holds queue instance coming from main thread
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestProducer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        //create serversocket instance on port 19029
        ServerSocket serverSocket = new ServerSocket(19029);
        while (true) {
            try {
                //keep accept connections
                Socket socket = serverSocket.accept();
                //add socket to queue
                queue.offer(socket);
            } catch (ConnectException ce) {//handle exception
            } catch (SocketException e) {//handle exception
            }
        }
    } catch (IOException ex) {//handle exception}
}

RequestConsumer thread

//this holds queue instance coming from main thread, same as requestproducer
ConcurrentLinkedQueue<Socket> queue

//constructor, initiate queue
public RequestConsumer(
    ConcurrentLinkedQueue<Socket> queue
) {
    this.queue = queue;
}

public void run() {
    try {
        Socket socket = null;
        while (true) {
            //get head of the queue (socket instance)
            socket = queue.poll();
            if (null != socket) {
                //process data stream
                String in = DataStreamUtil.parseUtfSockStream(socket.getInputStream());
                //close socket conection
                socket.close();
                //excecute database insert of processed data
                excecuteDbInsert(in);
            }
        }
    } catch (IOException | ParseException ex) {//handle exceptions}
}

Note: no need to send response back to the client Also, i haven't tested this yet in concurrent environment.

My questions are,

  • what are the pros and cons of this approach ?
  • how can i improve this ?
  • any other suggestions are highly appreciated.
\$\endgroup\$
  • \$\begingroup\$ Please see jgroup a open source project which will do this for you in much better way.jgroups.org \$\endgroup\$ – Shivang Agarwal Nov 10 '17 at 8:46
  • \$\begingroup\$ yeah, i'll try that, so is this a good way to implement socket server ? \$\endgroup\$ – benjamin c Nov 10 '17 at 12:56
  • 1
    \$\begingroup\$ jgrouop one is good. so you can go for that if you want your one then let me know i will check and share with you :) please upvote my comment if you like it. \$\endgroup\$ – Shivang Agarwal Nov 13 '17 at 6:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.