如何在Spring中重用套接字连接以发送ISO8583消息

huangapple go评论41阅读模式
英文:

How to reuse the socket connection in spring for sending ISO8583 messages

问题

以下是您要翻译的内容:

"Can anyone help me in reusing the socket client for sending and receiving response in spring boot - The full java code is available in the git repo ; https://github.com/imohsenb/ISO8583-Message-Client-java.git

Plan is to open 10 / 15 threads in spring with isoclient object and reuse same thread to send and receive response. because each time we create socket its consuming more than 200 ms and original transaction another 250 ms.

ISOClient client = ISOClientBuilder.createSocket(HOST, PORT)
                .build();
        client.connect();
        String response = Arrays.toString(client.sendMessageSync(new SampleIsoMessage()));
        System.out.println("response = " + response);
        client.disconnect();

ISOClientBuilder Class

package com.imohsenb.ISO8583.builders;

import com.imohsenb.ISO8583.entities.ISOMessage;
import com.imohsenb.ISO8583.exceptions.ISOClientException;
import com.imohsenb.ISO8583.handlers.IOSocketHandler;
import com.imohsenb.ISO8583.handlers.NIOSocketHandler;
import com.imohsenb.ISO8583.handlers.SSLHandler;
import com.imohsenb.ISO8583.interfaces.ISOClient;
import com.imohsenb.ISO8583.interfaces.ISOClientEventListener;
import com.imohsenb.ISO8583.interfaces.SSLProtocol;
import com.imohsenb.ISO8583.interfaces.SocketHandler;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author Mohsen Beiranvand
 */
public class ISOClientBuilder {
    // ... 这里省略了部分代码 ...
}

如果您需要更多信息或其他帮助,请随时告诉我。

英文:

Can anyone help me in reusing the socket client for sending and receiving response in spring boot - The full java code is available in the git repo ; https://github.com/imohsenb/ISO8583-Message-Client-java.git

Plan is to open 10 / 15 threads in spring with isoclient object and reuse same thread to send and receive response. because each time we create socket its consuming more than 200 ms and original transaction another 250 ms.

ISOClient client = ISOClientBuilder.createSocket(HOST, PORT)
                .build();
        client.connect();
        String response = Arrays.toString(client.sendMessageSync(new SampleIsoMessage()));
        System.out.println("response = " + response);
        client.disconnect();

ISOClientBuilder Class

package com.imohsenb.ISO8583.builders;

import com.imohsenb.ISO8583.entities.ISOMessage;
import com.imohsenb.ISO8583.exceptions.ISOClientException;
import com.imohsenb.ISO8583.handlers.IOSocketHandler;
import com.imohsenb.ISO8583.handlers.NIOSocketHandler;
import com.imohsenb.ISO8583.handlers.SSLHandler;
import com.imohsenb.ISO8583.interfaces.ISOClient;
import com.imohsenb.ISO8583.interfaces.ISOClientEventListener;
import com.imohsenb.ISO8583.interfaces.SSLProtocol;
import com.imohsenb.ISO8583.interfaces.SocketHandler;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author Mohsen Beiranvand
 */
public class ISOClientBuilder {


    private static ClientBuilder clientBuilder;

    public static ClientBuilder createSocket(String host, int port) {
        clientBuilder = new ClientBuilder(host, port);
        return clientBuilder;
    }

    /**
     * ClientBuilder
     */
    public static class ClientBuilder {

        private DefaultISOClient client;
        /**
         * Create ISO Client after initializing
         * @param host socket Host
         * @param port socket ip
         */
        public ClientBuilder(String host, int port) {
            client = new DefaultISOClient();
            client.setSocketAddress(host,port);
        }

        /**
         * Sending with NIO (false) or Blocking IO (true)
         * @param blocking:true
         * @return {@link ClientBuilder}
         */
        public ClientBuilder configureBlocking(boolean blocking) {
            client.setBlocking(blocking);
            return this;
        }

        /**
         * Enable sending over SSL/TLS
         * @return {@link ClientBuilder}
         */
        public SSLProtocol enableSSL() {
            return client.enableSSL(new SSLHandler(this));
        }

        /**
         * Build ISOClient for sending label
         * @return {@link ClientBuilder}
         */
        public ISOClient build() {
            return client;
        }

        /**
         * set Timeout for read from socket
         * @param millisecond timeout in millisecond
         * @return {@link ClientBuilder}
         */
        public ClientBuilder setReadTimeout(int millisecond) {
            client.setReadTimeout(millisecond);
            return this;
        }

        /**
         * Set Message length in Byte
         * @param bytes default: 2 byte
         * @return {@link ClientBuilder}
         */
        public ClientBuilder length(int bytes) {
            client.setLength(bytes);
            return this;
        }

        /**
         * Set event listener for dispatch events
         * @param eventListener Implementation of {@link ISOClientEventListener}
         * @return {@link ClientBuilder}
         */
        public ClientBuilder setEventListener(ISOClientEventListener eventListener) {
            if(eventListener != null)
                client.setEventListener(eventListener);
            return this;
        }
    }

    private static class DefaultISOClient implements ISOClient {

        private SSLHandler sslHandler = null;
        private SocketHandler socketHandler;
        private ByteBuffer buffer;
        private boolean blocking = true;
        private volatile boolean connected = false;
        private String host;
        private int port;
        private int readTimeout = 10000;
        private int length = 2;

        private final Object lock = new Object();
        private ISOClientEventListener isoClientEventListener;

        DefaultISOClient()
        {
            if(this.blocking) {
                socketHandler = new IOSocketHandler();
            }else{
                socketHandler = new NIOSocketHandler();
            }

            isoClientEventListener = new EmptyISOClientEventListener();
        }

        public void connect() throws ISOClientException, IOException {
            isoClientEventListener.connecting();

            if(sslHandler != null)
                socketHandler.init(host, port, isoClientEventListener, sslHandler);
            else socketHandler.init(host,port, isoClientEventListener);

            socketHandler.setReadTimeout(this.readTimeout);
            this.connected = true;

            isoClientEventListener.connected();
        }

        public void disconnect() {
            if(socketHandler!=null)
                socketHandler.close();
            if(buffer!=null) {
                buffer.flip();
                buffer.put(ByteBuffer.allocate(buffer.limit()));
                buffer = null;
            }
            connected = false;

            isoClientEventListener.disconnected();

        }

        private ByteBuffer initBuffer(ISOMessage isoMessage) {
            int len = isoMessage.getBody().length + isoMessage.getHeader().length;

            buffer = ByteBuffer.allocate(len + length);

            if(length > 0)
            {
                byte[] mlen = ByteBuffer.allocate(4).putInt(len).array();
                buffer.put(Arrays.copyOfRange(mlen, 2,4));
            }

            buffer.put(isoMessage.getHeader())
                    .put(isoMessage.getBody());

            return buffer;
        }

        public byte[] sendMessageSync(ISOMessage isoMessage) throws ISOClientException, IOException {

            byte[] result = new byte[0];

            synchronized (lock) {
                if (!isConnected())
                    throw new ISOClientException("Client does not connected to a server!");

                ByteBuffer buffer = initBuffer(isoMessage);


                result = socketHandler.sendMessageSync(buffer, length);
            }

            return result;
        }

        @Override
        public boolean isConnected() {
            return socketHandler != null && socketHandler.isConnected();
        }

        @Override
        public boolean isClosed() {
            return socketHandler != null && socketHandler.isClosed();
        }

        @Override
        public void setEventListener(ISOClientEventListener isoClientEventListener) {
            this.isoClientEventListener = isoClientEventListener;
        }

        private void setSocketAddress(String host, int port) {
            this.host = host;
            this.port = port;
        }

        private SSLHandler enableSSL(SSLHandler sslHandler) {
            this.sslHandler = sslHandler;
            return sslHandler;
        }

        private void setBlocking(boolean blocking) {
            this.blocking = blocking;
        }


        private void setReadTimeout(int readTimeout) {
            this.readTimeout = readTimeout;
        }

        private void setLength(int length) {
            this.length = length;
        }

        private int getLength() {
            return length;
        }

    }

    private static class EmptyISOClientEventListener implements ISOClientEventListener {
        @Override
        public void connecting() {

        }

        @Override
        public void connected() {

        }

        @Override
        public void connectionFailed() {

        }

        @Override
        public void connectionClosed() {

        }

        @Override
        public void disconnected() {

        }

        @Override
        public void beforeSendingMessage() {

        }

        @Override
        public void afterSendingMessage() {

        }

        @Override
        public void onReceiveData() {

        }

        @Override
        public void beforeReceiveResponse() {

        }

        @Override
        public void afterReceiveResponse() {

        }
    }


}

答案1

得分: 1

It's not the socket creation that takes time, it's the connection establishment. A 'socket' is merely a local data structure that (on the client side) can hold a connection.

这不是套接字创建花费时间,而是连接建立。'socket'只是一个本地数据结构,可以(在客户端上)保存连接。

It appears you intentionally disconnect after each transaction.

看起来你在每个事务之后故意断开连接。

ISOClient client = ISOClientBuilder.createSocket(HOST, PORT)
.build();
client.connect();
String response = Arrays.toString(client.sendMessageSync(new SampleIsoMessage()));
System.out.println("response = " + response);
client.disconnect();

If your protocol allows it and your server allows it, and multiple transactions all go to the same host+port, then don't build a new client for each transaction, and don't disconnect after each transaction. Keep the client around for re-use.

如果您的协议允许,并且服务器允许,并且多个事务都发送到相同的主机+端口,则不要为每个事务构建新的客户端,并且不要在每个事务之后断开连接。保留客户端以供重复使用可能会涉及安全问题。我不够了解情况,无法对此发表评论。

英文:

It's not the socket creation that takes time, it's the connection establishment. A 'socket' is merely a local data structure that (on the client side) can hold a connection.

It appears you intentionally disconnect after each transaction.

ISOClient client = ISOClientBuilder.createSocket(HOST, PORT)
                .build();
        client.connect();
        String response = Arrays.toString(client.sendMessageSync(new SampleIsoMessage()));
        System.out.println("response = " + response);
        client.disconnect();

If your protocol allows it and your server allows it, and multiple transactions all go to the same host+port, then don't build a new client for each transaction, and don't disconnect after each transaction. Keep the client around for re-use.

There may be security implications in such re-use. I don't know the situation well enough to say anything about that.

huangapple
  • 本文由 发表于 2020年8月1日 03:38:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63198146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定