kpavlov / jreactive-8583

Kotlin/Java Client & Server for ISO8583 & Netty
Apache License 2.0
320 stars 144 forks source link

Request/Response Practice #74

Closed mohbadar closed 4 years ago

mohbadar commented 4 years ago

How can I receive the response of the request that I have sent to the third party server? I am struggling with this challenge for few days. I have tried SynchronizedQueue<Promise> and some other techniques, but they were all unsuccessful.

kpavlov commented 4 years ago

Hi In the first place make sure you receive an answer from remote server. Then enable logging.

mohbadar commented 4 years ago

This my sample implementation : Yes, I can receive messages on listener.


import com.github.kpavlov.jreactive8583.IsoMessageListener;
import com.github.kpavlov.jreactive8583.client.ClientConfiguration;
import com.github.kpavlov.jreactive8583.client.Iso8583Client;
import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.MessageFactory;
import com.solab.iso8583.parse.ConfigParser;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

public class IsoClient {

    private final static String HOST = "localhost";
    private final static int PORT = 6106;
    public static MessageFactory<IsoMessage> messageFactory;
    public static Iso8583Client<IsoMessage> client;
    private static final BlockingQueue<Promise<IsoMessage>> queue = new SynchronousQueue<Promise<IsoMessage>>(true);

    private  static MessageFactory<IsoMessage> clientMessageFactory() throws IOException {
        final MessageFactory<IsoMessage> messageFactory = ConfigParser.createDefault();
        messageFactory.setUseBinaryBitmap(true);
        messageFactory.setCharacterEncoding(StandardCharsets.US_ASCII.name());
        return messageFactory;
    }

    private static Iso8583Client<IsoMessage> iso8583Client() throws IOException {
        SocketAddress socketAddress = new InetSocketAddress(HOST, PORT);
        final ClientConfiguration configuration = ClientConfiguration.newBuilder()
                .logSensitiveData(true)
                .workerThreadsCount(4)
                .build();
        return new Iso8583Client<>(socketAddress, configuration, clientMessageFactory());
    }

    private static void init() throws IOException {
        messageFactory = clientMessageFactory();
        client = iso8583Client();

    }

    public static void main(String[] args) throws Exception {

        if (client == null || messageFactory == null) {
            init();
        }

        client.addMessageListener(new IsoMessageListener<IsoMessage>() {
            @Override
            public boolean applies(IsoMessage t) {
                return true;
            }

            @Override
            public boolean onMessage(ChannelHandlerContext chc, IsoMessage t) {

                System.out.println("RECIEVED MSG: " + t.debugString());
                return true;
            }

        });

        client.init();
        //        connect
        client.connect();
//        client.connectAsync();

        if (client.isConnected()) {

            System.out.println("CONNECTION ON " + client.getSocketAddress());
            IsoMessage message = messageFactory.newMessage(0x1804);
            send(message);
        }

//        client.shutdown();
    }

    public static void send(IsoMessage message) throws Exception {
        System.out.println("Sending to SV");

        client.send(message);

//        Here I need the response of request

//    ****    this way
//        IsoMessage isoMessage = client.send().get();

// *****       OR
//                .addListener(new GenericFutureListener<Future<? super IsoMessage>>() {
//            @Override
//            public void operationComplete(Future<? super IsoMessage> future) throws Exception {
//                System.out.println("Message Exchange"+ future.get().toString());
//            }
//        });

    }
}
kpavlov commented 4 years ago

You need to handle server response in client's listener. Once you get expected response (you may get anything from server, BTW), the listener may notify an external Future pr push response to concurrent queue.

mohbadar commented 4 years ago

Here is the log example:


13:19:13.192 [nioEventLoopGroup-3-1] DEBUG com.github.kpavlov.jreactive8583.netty.pipeline.IsoMessageLoggingHandler - [id: 0xa668fb93, L:/127.0.0.1:53620 - R:localhost/127.0.0.1:6106] FLUSH
13:19:13.202 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
13:19:13.202 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
13:19:13.203 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@19a09db6
13:19:13.237 [nioEventLoopGroup-3-1] DEBUG com.github.kpavlov.jreactive8583.netty.pipeline.IsoMessageLoggingHandler - [id: 0xa668fb93, L:/127.0.0.1:53620 - R:localhost/127.0.0.1:6106] READ: Message: 18140000000000000000
MTI: 0x1814
13:19:13.237 [nioEventLoopGroup-3-1] DEBUG com.github.kpavlov.jreactive8583.netty.pipeline.IsoMessageLoggingHandler - [id: 0xa668fb93, L:/127.0.0.1:53620 - R:localhost/127.0.0.1:6106] READ COMPLETE
13:19:13.238 [nioEventLoopGroup-3-1] DEBUG com.github.kpavlov.jreactive8583.netty.pipeline.CompositeIsoMessageHandler - Handling IsoMessage[@type=0x1814] with af.asr.iso8583_test.IsoClient$1@5e45379
RECIEVED MSG: 18140000000000000000
mohbadar commented 4 years ago

Could you please provide more information or a sample implementation?

mohbadar commented 4 years ago

I have achieved the goal by using ConcurrentHashMap.