<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.ice-online.com/index.php?action=history&amp;feed=atom&amp;title=NXM_Help_RMIF</id>
	<title>NXM Help RMIF - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.ice-online.com/index.php?action=history&amp;feed=atom&amp;title=NXM_Help_RMIF"/>
	<link rel="alternate" type="text/html" href="https://wiki.ice-online.com/index.php?title=NXM_Help_RMIF&amp;action=history"/>
	<updated>2026-06-09T22:43:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>https://wiki.ice-online.com/index.php?title=NXM_Help_RMIF&amp;diff=587&amp;oldid=prev</id>
		<title>ConvertBot: Created page with &quot;&lt;div style=&quot;background-color: #eef9ff; border: 1px solid #999; padding: 10px;&quot;&gt;&amp;uarr; ''Go to the full list of NXM Help pages''.&lt;/div&gt; &lt;onlyinclude&gt; === RMIF - th...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.ice-online.com/index.php?title=NXM_Help_RMIF&amp;diff=587&amp;oldid=prev"/>
		<updated>2020-04-27T18:39:28Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;div style=&amp;quot;background-color: #eef9ff; border: 1px solid #999; padding: 10px;&amp;quot;&amp;gt;&lt;a href=&quot;/NXM_Help&quot; title=&quot;NXM Help&quot;&gt;↑ &amp;#039;&amp;#039;Go to the full list of NXM Help pages&amp;#039;&amp;#039;&lt;/a&gt;.&amp;lt;/div&amp;gt; &amp;lt;onlyinclude&amp;gt; === RMIF - th...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;background-color: #eef9ff; border: 1px solid #999; padding: 10px;&amp;quot;&amp;gt;[[NXM_Help|&amp;amp;uarr; ''Go to the full list of NXM Help pages'']].&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;onlyinclude&amp;gt;&lt;br /&gt;
=== RMIF - the Remote Midas InterFace protocol.&amp;lt;span id=&amp;quot;RMIF&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The RMIF protocol is a take-off on Java's RMI (Remote Method Invocation).&lt;br /&gt;
&lt;br /&gt;
Java's RMI is designed to make objects at a remote site accessible&lt;br /&gt;
as if they are local objects.  A local reference to the remote object is&lt;br /&gt;
created and method calls on the local reference are passed to the&lt;br /&gt;
remote object via a transport layer, usually TCPIP.  The method name&lt;br /&gt;
and its arguments are serialized, sent to the remote processor, and&lt;br /&gt;
executed.  The optional resulting object is serialized, sent back to&lt;br /&gt;
the local processor and reconstructed in the objects local reference.&lt;br /&gt;
&lt;br /&gt;
The main purpose of the RMIF protocol is to allow NeXtMidas GUIs to control&lt;br /&gt;
Midas applications at remote sites.  While the protocol may be applied to&lt;br /&gt;
other problems, it's primary goal is to minimize link bandwidth for data&lt;br /&gt;
displays and respond robustly to network drop-outs common to real-world&lt;br /&gt;
long-distance multi-hop links.&lt;br /&gt;
&lt;br /&gt;
=== RMI - Java's Remote Method Invocation protocol.&amp;lt;span id=&amp;quot;RMI&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
RMI was not used directly for a number of reasons:&lt;br /&gt;
&lt;br /&gt;
# the server side applications are not typically Java based (C,C++,FORTRAN).&lt;br /&gt;
# the standard RMI implementation is layered on TCP, which severely&lt;br /&gt;
#: limits throughput and robustness over real-world links.&lt;br /&gt;
# object serialization requires unnecessary over-head and&lt;br /&gt;
#: data conversions to/from network ordering for data displays.&lt;br /&gt;
&lt;br /&gt;
The RMI reference was kept to make it easier for developers that may have&lt;br /&gt;
experience with Java RMI.  The concepts and methodology were paralleled&lt;br /&gt;
wherever possible.&lt;br /&gt;
&lt;br /&gt;
The current implementation of RMIF is layered on top of UDP.  All routing to&lt;br /&gt;
and from remote objects is handled by the UDP header.  There is no subrouting&lt;br /&gt;
within the RMIF protocol.  An RMIF object is defined by a node name (or network&lt;br /&gt;
address) and a port number.&lt;br /&gt;
&lt;br /&gt;
=== Header - The RMIF 8-byte packet header.&amp;lt;span id=&amp;quot;Header&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The UDP payload begins with an 8-byte RMIF header.  The RMIF protocol uses the&lt;br /&gt;
8-byte header to, in effect, compress the overhead that would be necessary to&lt;br /&gt;
serialize a method call.  The header bytes (in order) are:&lt;br /&gt;
&lt;br /&gt;
 FUNC - defines the method to call&lt;br /&gt;
 FLAG - is the protocol version number and options mask&lt;br /&gt;
 INFO - channel number for fast routing of monitored properties&lt;br /&gt;
 REP  - packet data representation (VAX|IEEE|EEEI)&lt;br /&gt;
 SEQ  - sequence number (0-127) for Reliable packets&lt;br /&gt;
 TRY  - number of re-sends for Reliable packets&lt;br /&gt;
 RPT  - report sequence number&lt;br /&gt;
 ADJ  - number of bytes in adjunct header&lt;br /&gt;
&lt;br /&gt;
The size of the data portion of the payload is the UDP packet size minus the&lt;br /&gt;
8 byte header and the adjunct header if ADJ&amp;gt;0.&lt;br /&gt;
&lt;br /&gt;
=== AdjunctHeader - The RMIF adjunct header.&amp;lt;span id=&amp;quot;AdjunctHeader&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The optional adjunct header follows directly after the 8-byte RMIF header. It&lt;br /&gt;
must be a multiple of 8-bytes as well for alignment purposes.  The currently&lt;br /&gt;
supported adjunct header options are:&lt;br /&gt;
&lt;br /&gt;
 ADJ_TIME   - an 8-byte double precision time in J1950 seconds&lt;br /&gt;
 ADJ_OFFSET - an 8-byte double precision file offset for MFTP&lt;br /&gt;
&lt;br /&gt;
In each of these cases, the ADJ field in the RMIF header equals 8. The data&lt;br /&gt;
portion of the payload will start at the 16th byte instead of the 8th.&lt;br /&gt;
&lt;br /&gt;
=== Functions - The currently defined RMIF functions.&amp;lt;span id=&amp;quot;Functions&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The currently supported functions (or method calls) are:&lt;br /&gt;
&lt;br /&gt;
 GET  - request the value of a named property&lt;br /&gt;
 RET  - return the value for a GET request&lt;br /&gt;
 SET  - set a named property&lt;br /&gt;
 ACK  - acknowledge the value for a SET request&lt;br /&gt;
 OPEN - open connection to a remote or a channel to one of it's properties&lt;br /&gt;
 OPENED - acknowledges an OPEN request&lt;br /&gt;
 CLOSE - close connection to a remote or a channel to one of it's properties&lt;br /&gt;
 CLOSED - acknowledges an CLOSE request&lt;br /&gt;
 MODIFY - modify a channel connection&lt;br /&gt;
 PING - request keep-alive status&lt;br /&gt;
 PONG - return keep-alive status&lt;br /&gt;
 DHDR - process data header&lt;br /&gt;
 DBUF - process data buffer&lt;br /&gt;
 DBUFC - process compressed data buffer&lt;br /&gt;
 DBUFD - process compressed data buffer&lt;br /&gt;
 GETPROP - request list of published properties&lt;br /&gt;
 RETPROP - return number of properties or property names&lt;br /&gt;
 RECEIPT - acknowledge receipt of a reliable packet&lt;br /&gt;
 MFTP - process the Midas File Transfer Protocol&lt;br /&gt;
&lt;br /&gt;
=== Methods - How RMIF packets are converted to function calls.&amp;lt;span id=&amp;quot;Methods&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The RMIish components of the protocol are accomplished with the GET, RET,&lt;br /&gt;
SET, and ACK functions.  The Java language suggests the use of public methods&lt;br /&gt;
beginning with &amp;quot;set&amp;quot; and &amp;quot;get&amp;quot; to provide a common interface to an object's&lt;br /&gt;
public properties.  To allow combining multiple SETs or GETs in a single&lt;br /&gt;
network packet, the data portion of the GET|RET|SET|ACK packet is a&lt;br /&gt;
serialized table class.  The key for each table entry is the body of the&lt;br /&gt;
method name, and the value for each key is the method's argument.  For&lt;br /&gt;
example, to call the setFreq, setAmp, and setOptions methods on a remote&lt;br /&gt;
object the data portion of a RMIF packet with the FUNC=SET would be:&lt;br /&gt;
&lt;br /&gt;
 {FREQ=1.3E6,AMP=1,OPTIONS={MODE=1,AXIS=NONE}}&lt;br /&gt;
&lt;br /&gt;
The syntax is all ASCII to allow using off-the-shelf tools or XML parsers&lt;br /&gt;
to monitoring network traffic.  Note that the setOptions() method has more&lt;br /&gt;
than one argument.  To do this, the arguments are expressed as another table,&lt;br /&gt;
with each argument being named.  This again aids in monitoring/debugging.&lt;br /&gt;
&lt;br /&gt;
=== RMIvsRMIF - Why RMIF and UDP instead of RMI and TCP.&amp;lt;span id=&amp;quot;RMIvsRMIF&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The RMIF protocol uses considerably less bandwidth than RMIs serialization&lt;br /&gt;
of calls for most functions.  Also, TCP socket writes eventually end up in&lt;br /&gt;
TCP packets that have more overhead than UDP.  In addition, when and where&lt;br /&gt;
socket writes get broken into TCP packets is not under the application's&lt;br /&gt;
control.  If network dropouts cause a TCP packet to be dropped, this may&lt;br /&gt;
or may not lie on a functional boundary for a method call making graceful&lt;br /&gt;
recovery difficult.&lt;br /&gt;
&lt;br /&gt;
Another benefit of UDP is throughput.  In TCP, system drivers usually&lt;br /&gt;
limit the number of outstanding packets to 12.  This means that until the&lt;br /&gt;
remote connection receives the packet and acknowledges receipt, the local&lt;br /&gt;
socket will hold-off outgoing packets.  Using the typical maximum&lt;br /&gt;
transfer unit, MTU, of 1500 bytes and roundtrip delay of 500 ms, we can&lt;br /&gt;
calculate a maximum sustained transfer rate of 12*1500/.5 = 36kby/sec.&lt;br /&gt;
&lt;br /&gt;
The RMIF protocol implements the reliable portion of the TCP layer at the&lt;br /&gt;
user level, allowing the application to set the maximum number of outstanding&lt;br /&gt;
packets (default=12,max=128) and which packets to send reliably or unreliably.&lt;br /&gt;
Typically, data display packets are sent unreliably, and all others reliably.&lt;br /&gt;
Unreliable packets set the SEQ header byte to -1.  Reliable packets have SEQ&lt;br /&gt;
set to a one-up counter (0-127) by the sender, along with a retry count TRY.&lt;br /&gt;
If the sender does not get a receipt after a tunable tolerance plus the last&lt;br /&gt;
measured round trip delay, it will resend the packet.  By combining the&lt;br /&gt;
reliable and unreliable streams in the same socket, we can implement priority&lt;br /&gt;
schemes that, for instance, favor controls over data.&lt;br /&gt;
&lt;br /&gt;
Another benefit of UDP is that it is connectionless.  A UDP port on a machine&lt;br /&gt;
is basically a bucket on a node to catch network packets that are thrown at it.&lt;br /&gt;
They can be thrown from anywhere, from any number of sources, in any order.&lt;br /&gt;
Each packet contains the network address and port number of who threw the&lt;br /&gt;
packet, so you can throw something back if called for.  Then you're done.&lt;br /&gt;
No opens, no closes.  Network problems cannot cause connections to hang in an&lt;br /&gt;
unknown state, because there never is a connection.  This leaves the timing&lt;br /&gt;
out and recovery to the application, where appropriate tuning may be applied.&lt;br /&gt;
&lt;br /&gt;
Most of the protocol handling will be administered by an RMIF primitive or&lt;br /&gt;
component on each end of the connection.  This primitive should insulate the&lt;br /&gt;
framework from the RMIF protocol and convert the method calls to appropriate&lt;br /&gt;
constructs for that framework.  [[NXM_Help_RMIF|See the RMIF]] Explain File for more details.&lt;br /&gt;
&lt;br /&gt;
=== MFTP - The Midas File Transfer Protocol&amp;lt;span id=&amp;quot;MFTP&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
An RMIF connection also supports file transfers in both directions.&lt;br /&gt;
The client typically requests a file from the server, however, the client&lt;br /&gt;
can post a file to the server if allowed.&lt;br /&gt;
&lt;br /&gt;
The low level packets for accessing a file are as follows:&lt;br /&gt;
&lt;br /&gt;
Client:  func=MFTP data={FUNC=EXIST,NAME=filename}&lt;br /&gt;
Server:  func=MFTP data={FUNC=EXIST,NAME=filename,EXISTS=Y|N}&lt;br /&gt;
&lt;br /&gt;
Client:  func=MFTP data={FUNC=OPEN,NAME=filename,RATE=byte/sec,PKTLEN=bytes}&lt;br /&gt;
Server:  func=MFTP data={FUNC=OPEN,NAME=filename,LENGTH=bytesAtOpen}&lt;br /&gt;
&lt;br /&gt;
Client:  func=MFTP data={FUNC=READ,NAME=filename,OFFSET=byte,LENGTH=bytes,RATE=byte/sec,PKTLEN=bytes}&lt;br /&gt;
Server:  func=MFTP data={FUNC=READ,NAME=filename,OFFSET=byte,LENGTH=availbytes}&lt;br /&gt;
Server:  func=DBUF adj=offset data=binaryDataBuffer     (multiple packets)&lt;br /&gt;
&lt;br /&gt;
Client:  func=MFTP data={FUNC=CLOSE,NAME=filename}&lt;br /&gt;
Server:  func=MFTP data={FUNC=CLOSE,NAME=filename,LENGTH=bytesAtClose}&lt;br /&gt;
&lt;br /&gt;
The RATE and PKTLEN specifiers are optional. They default to RATE=2e6 and PKTLEN=8K.&lt;br /&gt;
&lt;br /&gt;
This level of protocol deals with raw files or an IOResource in NeXtMidas.&lt;br /&gt;
It does not understand Midas file headers, detached headers, or detached packet files.&lt;br /&gt;
This must be handled by the calling routine, usually the DataFile class.&lt;br /&gt;
&lt;br /&gt;
For example, an RMIF server on port 9001 can serve a file using the command:&lt;br /&gt;
&lt;br /&gt;
 nM&amp;gt; noop/gpw  mftp://remoteHostName:9001/remoteFileName  localFileName&lt;br /&gt;
&lt;br /&gt;
where the /gpw invokes a graphical progress widget.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
[[Category:NXM_Help]]&lt;/div&gt;</summary>
		<author><name>ConvertBot</name></author>
		
	</entry>
</feed>