简体   繁体   English

如何重用 spring 中的套接字连接来发送 ISO8583 消息

[英]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;谁能帮我重用套接字客户端以在 spring 引导中发送和接收响应 - 完整的 java 代码可在 git 存储库中获得; https://github.com/imohsenb/ISO8583-Message-Client-java.git 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.计划是使用 isoclient object 在 spring 中打开 10 / 15 个线程,并重用同一线程来发送和接收响应。 because each time we create socket its consuming more than 200 ms and original transaction another 250 ms.因为每次我们创建套接字时,它消耗超过 200 毫秒,而原始事务又消耗了 250 毫秒。

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 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() {

        }
    }


}

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.如果您的协议允许它并且您的服务器允许它,并且多个事务都 go 到相同的主机+端口,那么不要为每个事务构建一个新客户端,并且在每个事务之后不要断开连接。 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.我不太了解情况,无法对此发表任何评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM