QMUX client reconnecting after timeout

53 views
Skip to first unread message

csr

unread,
Jun 25, 2025, 5:43:15 AMJun 25
to jPOS Users
Hi,
Our application acts as a gateway. It receives requests from our clients and forwards them to the server. To connect with the server, we are using Q2 and QMUX in our application.

We are able to establish a connection with the server when Q2 environment started, but the connection drops after a timeout period and the system then attempts to reconnect.

Our server expects the following behaviour:
1. Once the connection is established, the client should hold the connection.
2. The client should send a request to the server only when a request is received at the gateway.
3. The client should attempt to reconnect only if there is no response from the server or the connection is dropped.

Kindly let us know if there is any issue with our current approach and how we can achieve the desired behaviour.
Also attached our JPos configuration

<?xml version="1.0" encoding="UTF-8"?>
<mux class="org.jpos.q2.iso.QMUX" logger="Q2" name="test-mux">
    <in>client-receive</in>
    <out>client-send</out>
    <ready>test-channel.ready</ready>
    <unhandled>myunhandledqueue</unhandled>
    <key>2 7</key>
</mux>

<?xml version="1.0" encoding="UTF-8"?>
<channel-adaptor name='test-channel'
                 class="org.jpos.q2.iso.ChannelAdaptor" logger="Q2">
    <channel class="org.jpos.iso.channel.VAPChannel" logger="Q2" realm="test-channel"
                 packager="org.jpos.iso.packager.GenericPackager">      
        <property name="packager-config" value="iso/base1.xml" />
        <property name="host" value="10.1.99.79" />
        <property name="port" value="9999" />
        <property name="connection-timeout" value="5000" />
        <property name="timeout" value="5000" />
        <property name="keep-alive" value="true" />  
 
    </channel>
<request-listener class="TestRequestListener"/>
<!--    <ignore-iso-exceptions>yes</ignore-iso-exceptions>-->
    <in>client-send</in>
    <out>client-receive</out>
    <reconnect-delay>30000</reconnect-delay>
</channel-adaptor>

 // Start Q2 environment
            Q2 q2 = new Q2("c:/projects/jpos-qmux/deploy/");
             q2.start();

Regards
Reddy

Andrés Alcarraz

unread,
Jun 25, 2025, 5:54:02 AMJun 25
to jpos-...@googlegroups.com

Hi there.

What is the timeout after which you see the disconnects? Does it happen only when there are no transactions or also when there are?

----
Enviado desde mi móvil, disculpas por la brevedad.

Sent from my cellphone, I apologize for the brevity.

Andrés Alcarraz.

--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/jpos-users/0b234979-3a01-4dc4-bf89-0d4bf3a339f1n%40googlegroups.com.

csr

unread,
Jun 25, 2025, 11:38:40 PMJun 25
to jPOS Users
Hi Andres,
In both cases we are seeing the disconnect after the timeout property interval
<property name="timeout" value="5000" />

I am attaching the JPOS logs for both cases.

1. Q2 Started without sending the request

<log realm="Q2.system" at="2025-06-26T11:27:58.472" lifespan="5ms">
  <info>
    deploy: C:\projects\jpos-qmux-sample\deploy\logger.xml
  </info>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:27:58.517" lifespan="5ms">
  <connect>
    Try 0 10.1.99.79:9999
  </connect>
</log>
!!! Connection Established...
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:28:03.532" lifespan="5014ms">
  <receive>
    <io-timeout/>
  </receive>
</log>
<log realm="org.jpos.q2.iso.ChannelAdaptor" at="2025-06-26T11:28:03.533">
  <warn>
    channel-receiver-client-receive
    Read timeout / EOF - reconnecting
  </warn>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:28:33.655">
  <connect>
    Try 0 10.1.99.79:9999
  </connect>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:28:38.666" lifespan="5010ms">
  <receive>
    <io-timeout/>
  </receive>
</log>
<log realm="org.jpos.q2.iso.ChannelAdaptor" at="2025-06-26T11:28:38.669">
  <warn>
    channel-receiver-client-receive
    Read timeout / EOF - reconnecting
  </warn>
</log>

2. Q2 Started by sending the request

<log realm="Q2.system" at="2025-06-26T11:19:28.372" lifespan="4ms">
  <info>
    deploy: C:\projects\jpos-qmux-sample\deploy\logger.xml
  </info>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:19:28.416" lifespan="8ms">
  <connect>
    Try 0 10.1.99.79:9999
  </connect>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:19:30.453" lifespan="1ms">
  <send>
    <isomsg direction="outgoing">
      <!-- org.jpos.iso.packager.GenericPackager[C:\\projects\\jpos-qmux-sample\\iso\\base1.xml] -->
      <header>16010200500000009393060000000000000000000000</header>
      <field id="0" value="0100"/>
      <field id="2" value="1234567890123456"/>
      <field id="3" value="000000"/>
      <field id="4" value="000000010000"/>
      <field id="7" value="0626111930"/>
      <field id="11" value="000001"/>
      <field id="37" value="123456789012"/>
      <field id="41" value="12345678"/>
      <field id="49" value="840"/>
    </isomsg>
  </send>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:19:30.643" lifespan="2226ms">
  <receive>
    <isomsg direction="incoming">
      <!-- org.jpos.iso.packager.GenericPackager[C:\\projects\\jpos-qmux-sample\\iso\\base1.xml] -->
      <header>16010200629393060000000000000000000000000000</header>
      <field id="0" value="0110"/>
      <field id="2" value="1234567890123456"/>
      <field id="3" value="000000"/>
      <field id="4" value="000000010000"/>
      <field id="7" value="0626111930"/>
      <field id="11" value="000001"/>
      <field id="37" value="123456789012"/>
      <field id="38" value="007639"/>
      <field id="39" value="00"/>
      <field id="41" value="12345678"/>
      <field id="44" value="    2   2"/>
      <field id="49" value="840"/>
    </isomsg>
  </receive>
</log>
<<< Received response:

<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:19:35.657" lifespan="5012ms">
  <receive>
    <io-timeout/>
  </receive>
</log>
<log realm="org.jpos.q2.iso.ChannelAdaptor" at="2025-06-26T11:19:35.658">
  <warn>
    channel-receiver-client-receive
    Read timeout / EOF - reconnecting
  </warn>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:20:05.849" lifespan="2ms">
  <connect>
    Try 0 10.1.99.79:9999
  </connect>
</log>
<log realm="test-channel/10.1.99.79:9999" at="2025-06-26T11:20:10.853" lifespan="5002ms">
  <receive>
    <io-timeout/>
  </receive>
</log>
<log realm="org.jpos.q2.iso.ChannelAdaptor" at="2025-06-26T11:20:10.855">
  <warn>
    channel-receiver-client-receive
    Read timeout / EOF - reconnecting
  </warn>
</log>

murtuza chhil

unread,
Jun 26, 2025, 3:45:42 AMJun 26
to jPOS Users

The 5-second timeout you’ve configured is used to set the socket’s soTimeout. This defines how long the socket will wait for data to arrive during a read operation before throwing a SocketTimeoutException.
A good way to understand how this works is to look at the logs and trace it in the jPOS source code. All channel implementations in jPOS extend BaseChannel, which contains the relevant logic:

BaseChannel.java – lines 393–400

If your application sends periodic network message request responses (like ECHOs), that traffic will keep the connection active. You can also adjust the timeout value based on your understanding of expected message frequency — it’s perfectly fine to set it higher if needed.

When soTimeout is set, the channel blocks while reading bytes in the getMessageLength() method ( in the channel implementation of your configured channel). If no data arrives within the timeout window (e.g., 5 seconds), a SocketTimeoutException is thrown. Internally, this is caught as an InterruptedIOException, and you’ll see it logged as an “io-timeout” message.


-chhil

Mark Salter

unread,
Jun 26, 2025, 4:22:57 AMJun 26
to jpos-...@googlegroups.com
On 25/06/2025 10:43, csr wrote:
> Hi,
> Our application acts as a gateway. It receives requests from our
> clients and forwards them to the server. To connect with the server,
> we are using Q2 and QMUX in our application.

Can you share a brief description  of each component, including the
client system(s) connecting to you through to the backend system?

If you can include details like :-

- who is the server, and who the client

- if the connections are long lived or single use


You seem to control  all of the components, just not the Client's
systems connecting in - correct?

--

Mark

signature.asc
Message has been deleted

csr

unread,
Jun 29, 2025, 11:26:25 PMJun 29
to jPOS Users
Hi Mark,
Here are the details 
Client - Our own terminals and third party applications. The connection is short-lived with a timeout period of 45 secs.

Gateway - Our backend application that validate & processes the client requests and forward to the server. Connect is long lived. Expect the response for the individual request in 30secs.

Server - Third party application process requests received from different TPAs.

csr

unread,
Jun 30, 2025, 4:55:59 PMJun 30
to jPOS Users

Thank You Chhil for your explanation.

As the server does not recommend sending echo messages to keep the connection active, and also expects the connection to be held once established, we are planning the following approach:

  • Channel timeout is set to 2 hours to maintain the connection for a longer duration:

    xml
    <property name="connection-timeout" value="7200000" />
  • Request timeout is set to 30 seconds:

    java
    ISOMsg response = mux.request(request, 30000);

This approach helps us by maintaining the connection for longer period. If there is no activity, the connection times out after 2hrs and reconnects to the server. Additionally, individual requests will timeout after 30 seconds if no response is received from the server.

Is this a good approach?



Alejandro Revilla

unread,
Jun 30, 2025, 6:51:16 PMJun 30
to jpos-...@googlegroups.com
<property name="connection-timeout" value="7200000" />

Is used a connection time, in order to early fail if it can connect. A TCP/IP connection typically needs a few milliseconds to connect, waiting two hours is overkill.


i--
@apr


Mark Salter

unread,
Jul 1, 2025, 1:17:55 AMJul 1
to jpos-...@googlegroups.com

Hi Apr.

I think car is confused and has swapped to revising connection-timeout instead of

<property name="timeout" value="5000" />

@csr ch ge the right value, but speak to the central server and ask for some form of keep-alive so both they and you can know about and recover any outage.

Failing that perhaps generate some traffic that won't approve but you can send within the timeout period  sonthatbifbthe connection does break you can eal with it sooner instead of when you have a request to deliver.

--
Mark



-------- Original Message --------
signature.asc

murtuza chhil

unread,
Jul 1, 2025, 3:10:25 AMJul 1
to jPOS Users

Apologies for the earlier confusion, what I mentioned was incorrect.

<property name="connection-timeout" value="5000" /> 

The connect-timeout property specifies the maximum amount of time, in milliseconds, that the channel will wait to establish a TCP/IP connection to the remote host.
If the connection is successfully established within this time, the process continues.
If the remote host doesn't respond within this time (e.g., the server is down, a firewall is blocking the port, or the network is very slow), a
java.net.SocketTimeoutException is thrown, and the connection attempt fails. The ChannelAdaptor will then typically wait for its reconnect-delay and try again.

// org.jpos.iso.BaseChannel

public void setConfiguration (Configuration cfg)
    throws ConfigurationException
{
    // ...
    try {
        // First, the socket read timeout is set (defaults to 300000ms)
        setTimeout (cfg.getInt ("timeout", DEFAULT_TIMEOUT));

        // Then, connect-timeout is set.
        // *** IMPORTANT: If not specified, it defaults to the value of 'timeout' ***
        connectTimeout = cfg.getInt ("connect-timeout", timeout);
    } catch (SocketException e) {
        throw new ConfigurationException (e);
    }
}

The 5 min that you are seeing is because you have not configured the "timeout" property and jPOS default to 300000 thats 5mins.

You need to figure out what value is good for your "timeout". You do not need to worry about "connect-timeout", and if you do want to set it it can be a very small value.

// org.jpos.iso.BaseChannel
// 1. The default constant is defined here:
private static final int DEFAULT_TIMEOUT = 300000;



// 2. The constant is used here in setConfiguration():
public void setConfiguration (Configuration cfg)
    throws ConfigurationException
{
    // ... other configurations ...
    try {
        // If "timeout" property is not found in the configuration,
        // DEFAULT_TIMEOUT is used as the fallback value.
        setTimeout (cfg.getInt ("timeout", DEFAULT_TIMEOUT));
        connectTimeout = cfg.getInt ("connect-timeout", timeout);
    } catch (SocketException e) {
        throw new ConfigurationException (e);
    }
}
-chhil
Reply all
Reply to author
Forward
0 new messages