Question
Sai Vusirikapally · Apr 28, 2021

TCP Read(32000) with timeout period (5) failed

Hi everyone,

I'm currently developing a TCP inbound Service to read some XML sent from a TCP Operation that uses EnsLib.TCP.CountedOutboundAdapter.

1) I have tried EnsLib.TCP.Inbound adapter but that gives this error:

ERROR <Ens>ErrException: <METHOD DOES NOT EXIST>zinitConfig+7 ^Ens.Host.1 *%New,EnsLib.TCP.InboundAdapter -- logged as '-'
number - @'
Set ..Adapter = $classmethod(..#ADAPTER,"%New")'

Due to this, the adapter is unable to start listening for incoming connections.

2) When I use EnsLib.TCP.CountedXMLInboundAdapter or EnsLib.TCP.CountedInboundAdapter instead, then the adapter starts listening on a given port but the OnProcessinput() method is not receiving any data in the pInput stream. The stream is always empty and throws this error in the event log.

ERROR <Ens>ErrTCPReadBlockSize: TCP Read(32000) with timeout period (5) failed with : (1144):l version="1.0" encoding="UTF-8"?> Wsma2Message xmlns:ns1="urn:hl7-org:v3" ......

I tried changing the read timeout period all the way to 30 seconds but no use. The XML that is sent from the TCPCountedOutboundAdapter is as follows. 

<?xml version="1.0" encoding="UTF-8"?> <Wsma2Message xmlns:ns1="urn:hl7-org:v3"><Header><MessageID>PCEN1111111111111</MessageID><SendingOrganisationID>987654321</SendingOrganisationID><SendingIndividualID>5555555555</SendingIndividualID><ReceivingOrganisationID>123456</ReceivingOrganisationID><MessageType>JCCReferralOut</MessageType><CreationTime>2021-04-28T04:27:09.231Z</CreationTime></Header><Payload><V2> 1KB payload here</V2></Payload></Wsma2Message>

3) Can someone please explain, which TCP inbound adapter should I be using to receive an XML(Stream) sent by EnsLib.TCP.CountedOutboundAdapter?

Also if someone can explain how this counted adapter is different from normal inbound adapter, I would really appreciate that.

Thanks in advance.  

Product version: Ensemble 2017.1
$ZV: Cache for Windows (x86-64) 2017.2.1 (Build 801U) Wed Dec 6 2017 09:07:51 EST
00
2 0 6 84
Log in or sign up to continue

Replies

Hello Sai,

You might need to give more details on what your operation/service code looks like to determine what's going on. The WRC or your InterSystems rep could probably help with this.

The TCP adapter (including counted) docs can be found here. There are similar docs for the outbound, but it's pretty much the same but swapped for outbound:

Overview of Inbound TCP Adapter

"EnsLib.TCP.CountedInboundAdapter supports incoming TCP connections over which a TCP client and TCP listener exchange blocks of data, with the block length specified in the first 4 bytes of the block. The adapter uses the block length to acquire the meaningful portion of the data from the client application."

The above doc page also includes some guidance for setting up a TCP service.

Is there a particular reason you are using a Counted operation/service rather than generic TCP? I'm unfamiliar with the use case for the Counted adapters.

Connecting Systems with Interoperability Productions > Introducing Interoperability Productions > Connectivity Options

The above suggests that the counted adapters are meant for handling "counted data blocks".

The error you are getting seems to indicate a mismatch between the block size being sent, and the expected size. Looking at the traffic in a Wireshark could be helpful to understand what is happening.

To add-on to my initial post, I do think that if you use the same type of outbound adapter and inbound adapter (ie counted), it would be expected for the message to be accepted. Since you're sending XML I wonder why the operation isn't using the counted XML adapter. Hopefully, somebody with expertise in this area can help you.

Hi Vic,

Thank you so much for your reply. I'm about to contact WRC but thought someone will give me an answer here. And I also read the documentation of TCP adapters(Inbound&Outbound) and according to the documentation it should work. 

I wonder the same why the Operation is not using XML adapter. It was developed by someone about 5 years ago. Unfortunately this outbound operation is in an external system to my team's production. We have no control over it to make any modifications and the other team does not have any developers. 

To give you an idea of what we are doing, let me introduce

X- Source System(Ensemble)

Y-Legacy System(Some Legacy Application)

Z-Our new System (Ensemble)

There was a connection between X and Y. We asked the source system people to send us the same messages by creating another outbound operation using the same outbound class(Using Ensemble production UI). 

Later I inspected the outbound operation source code. It is using EnsLib.TCP.CountedOutboundAdapter to send the XML data.

So I imagined, if I use EnsLib.TCP.CountedInboundAdapter it will get data. But to my surprise, it is not working.

My Service code is very simple and Basic.

Include NthUtility Class NTH.Service.TestTcpInboundService Extends NTH.AIH.Service.BaseAimService
{ Parameter ADAPTER = "EnsLib.TCP.CountedInboundAdapter"; }


The BaseAimService Implements the OnProcessInput() method.

Method OnProcessInput(pInput As %Stream.GlobalCharacter, Output pOutput As %Stream.GlobalCharacter, ByRef pHint As %String) As %Status { $$$TRACE("Data"_pInput.Read() Quit $$$OK }

The trace never gives any data. pInput is always empty.  

Thanks again for the reply Vic,

I hope this helps you in answering my issue.

Hi Sai,

From the error log you attached before:

ERROR <Ens>ErrTCPReadBlockSize: TCP Read(32000) with timeout period (5) failed with : (1144):l version="1.0" encoding="UTF-8"?> Wsma2Message xmlns:ns1="urn:hl7-org:v3" ......

It seems to me it was very likely the sender and receiver are using different Charset or Endian settings (These settings are used by counted block transferring through TCP) thus the receiver can not retrieve the XML String from the bytes in the stream.
Would you mind to check whether your BO and BS are referring to the same Charset and Endian settings?

Hi Nicky,

Thanks for your reply. Yes, that was the 1st thing I checked and made sure when I got the error. The operation and the service both use the same Charset and Endian settings. I tried changing them to Little and JavaUTF but to no luck. I tried changing the timeout to various setting like 30, 60 seconds. But the XML file is only 2KB.

Hi Everyone, 

Thank you all for taking time to help me solve the issue.

After contacting the InterSystems support, we found that the issue is actually in a customized outbound TCP adapter. The adapter was sending a non counted stream using a counted adapter. 

My inbound adapter was expecting a counted stream(first 4 bytes containing the length of the message) but got non counted. So it failed always. I changed the outbound operation to use EnsLib.TCP.CountedXMLOutboundAdapter and my inbound to EnsLib.TCP.CountedInboundAdapter and they are working well together. 

Another thing I learned is that we can not use EnsLib.TCP.InboundAdapter directly in a service as this does not handle the incoming message and handles only connection setup. I think something like OnConnect() method needs to be overridden and implement our own logic to handle the incoming stream.

Once again, I appreciate your efforts. If you have similar issue or have questions regarding this, please send me a message and I will try to answer back soon.