Page 1 of 1

Publish/Subscribe issue with mixed RCF versions

Posted: Wed Aug 17, 2022 12:47 pm
by falk
Hello,
here is an issue with using RCF publish/subscribe with different RCF versions.
Publishing an event from a publisher (v3.2) to a subscriber (v2.2) is somehow silently swallowed. Nothing happens on subscriber side, no event is received and no error is thrown on either subscriber or publisher side.

Situation:
  • Publisher works with RCF v3.2
    Subscriber works with RCF 2.2
    Runtime version is set to 12 (RCF v2.2) on publisher side
The last point is described in the RCF user guide here: https://www.deltavsoft.com/doc/_version ... Versioning

Code: Select all

pubPtr->publish().getClientStub().setRuntimeVersion(12);
By setting the RCF_LOG to level 4 the following output is made on subscriber side:
RcfServer.cpp(568): [Thread: 6264][Time: 45953] RcfServer - received request. [Args: this=0000000002652F80, mRequest=(r.mToken = ( id = 0 ))(r.mSubInterface = )(r.mFnId = 0)(r.mSerializationProtocol = 1)(r.mMarshalingProtocol = 1)(r.mOneway = 1)(r.mClose = 0)(r.mService = )(r.mRuntimeVersion = 13)(r.mPingBackIntervalMs = 0)(r.mArchiveVersion = 0), ]
Comparing to the output of a communication between RCF v2.2-only publisher and subscriber the empty field r.mSubInterface stands out.
To compare here is the output from RCF v2.2 only:
RcfServer.cpp(568): [Thread: 4388][Time: 265812] RcfServer - received request. [Args: this=00000000030F40F0, mRequest=(r.mToken = ( id = 0 ))(r.mSubInterface = I_Publish)(r.mFnId = 0)(r.mSerializationProtocol = 1)(r.mMarshalingProtocol = 1)(r.mOneway = 1)(r.mClose = 0)(r.mService = )(r.mRuntimeVersion = 12)(r.mPingBackIntervalMs = 0)(r.mArchiveVersion = 0), ]
Looking into the relevant code locations for this field some comments hints that this field is no longer used in RCF 3(.2).
With a patch the interface name was again send to the subscriber. And the event was received and processed again there.

Here is the content of the patch:

Code: Select all

diff -U 3 src/RCF/MethodInvocation.cpp src/RCF/MethodInvocation.cpp
--- src/RCF/MethodInvocation.cpp	Sun Jul 12 14:15:49 2020
+++ src/RCF/MethodInvocation.cpp	Wed Aug 17 13:44:11 2022
@@ -403,7 +403,8 @@
 
     const std::string EmptyString;
 
-    ByteBuffer MethodInvocationRequest::encodeRequestHeader()
+    ByteBuffer MethodInvocationRequest::encodeRequestHeader(
+       const std::string &subInterface)
     {
         RCF_ASSERT(!mVecPtr || mVecPtr.unique());
         if (!mVecPtr)
@@ -454,7 +455,7 @@
         SF::encodeInt(0, *mVecPtr, pos);
 
         // mSubInterface - unused
-        SF::encodeString(EmptyString, *mVecPtr, pos);
+        SF::encodeString(subInterface, *mVecPtr, pos);
 
         SF::encodeInt(mFnId, *mVecPtr, pos);
         SF::encodeInt(mSerializationProtocol, *mVecPtr, pos);
diff -U 3 src/RCF/Marshal.cpp src/RCF/Marshal.cpp
--- src/RCF/Marshal.cpp	Sun Jul 12 14:15:49 2020
+++ src/RCF/Marshal.cpp	Wed Aug 17 09:37:34 2022
@@ -132,10 +132,14 @@
 
         ::RCF::CurrentClientStubSentry sentry(*this);
 
+        std::string interfaceName; // needed for backward compatibility
+        if (mRequest.mOneway && mRequest.mRuntimeVersion == 12)
+           interfaceName = mInterfaceName;
+
         mOut.reset(
             getSerializationProtocol(),
             32,
-            mRequest.encodeRequestHeader(),
+            mRequest.encodeRequestHeader(interfaceName),
             mRuntimeVersion,
             mArchiveVersion,
             mEnableSfPointerTracking);
diff -U 3 include/RCF/MethodInvocation.hpp include/RCF/MethodInvocation.hpp
--- include/RCF/MethodInvocation.hpp	Sun Jul 12 14:15:49 2020
+++ include/RCF/MethodInvocation.hpp	Wed Aug 17 09:31:08 2022
@@ -122,7 +122,7 @@
         void            setService(const std::string &service);
         int             getPingBackIntervalMs();
 
-        ByteBuffer      encodeRequestHeader();
+        ByteBuffer      encodeRequestHeader(const std::string &subInterface);
 
         void            encodeRequest(
                             const std::vector<ByteBuffer> & buffers,

Is there any other way, supported by the public RCF API, to ensure compatibility between those publisher and subscriber?

Kind regards
Falk

[Edit: patch with with deeper context created]