Differences in usage between .Net Remoting and REST

The difference from the previous way of using IMC, is that events are used.

Before this REST interface a method was always called directly through a reference.

Seen from a Rest IMCServer the difference is:

When calling Connect a Module to can determine if it is opened as an IMCServer. This “property “ is now changed and a call to a new property on LaunchInfo, called IsLauchedAsIMCServer let the module determine if it is to act as an IMCServer. Earlier a reference was delivered directly pointing to the initiating IMCClient. If IsLauchedAsIMCServer is true the IMC session is ready and the server can start, e.g. call IMCDataReady with any data as stated in the data types above.

Stop is received as an event from the ModuleApiProxy as IMCStop. From that point, the module can't use IMC.

The big difference is how to handle Command calls from the IMCServer.

The call will arrive as an event from the ModuleApiProxy as IMCCommandReceived, with the full IMCServerCommand, which the IMCServer has to extract by itself with DeserializeIMCCommandReceived(nt.CmdData)

Sample

private void EventPublisher_NotifyAsync(object sender, EventArgs e)
/// {
/// if (e is SharedLib.Models.NotifyEventArgs nt)
/// {
/// if (nt.Notification == SharedLib.Models.NotificationType.IMCCommandReceived)
/// {
/// // Very important to get data restored
/// SharedLib.Models.IMCServerCommand cmd = SharedLib.Helpers.IMCUtil.DeserializeIMCCommandReceived(nt.CmdData);
/// // cmd.UniqueId contains a guid generated by the MuduleApiProxy. The id must be returned in SetIMCCommandResult
/// object data = cmd.Data;
/// int result = cmd.Result;
/// // Call some method in your module to do the work and then return the data
/// this.CommandDoWork(cmd.CommandID, cmd.Info, ref data, ref result);
/// cmd.Result = result;
/// cmd.Data = data;
/// // Notice the use of the same instance of IMCServerCommand to avoid forgetting the cmd.UniqueId
/// moduleApiLib.SetIMCCommandResult(cmd);
/// }
/// if (nt.Notification == SharedLib.Models.NotificationType.IMCStop)
/// // When this is received the seeion is finished and DataRedy cant be called on the IMCClient
/// }
/// }

Now to be compatible with existing IMCClient modules, the result of the Command, has to be returned immediately. Since an event does not have any return value, this is done by calling SetIMCCommandResult.

Seen from a REST IMCClient the difference is:

Commands are wrapped in an IMCServerCommandObject.

IMCServerCommand cmd = new();
cmd.CommandID = (int)IMCCommandEnum.oc_SetProtocolNo;
cmd.Info = (int)number;

cmd = await _moduleApiLib.IMCCommand(cmd);

DataReady is in REST received as an event.

Sample:

private void ModuleApiLibOnEventReceived(object? sender, SharedLib.Models.NotifyEventArgs args)
{
if (args.Notification == NotificationType.IMCDataReady)
{
//Important do this to get data.
object obj = SharedLib.Helpers.IMCUtil.DeserializeIMCDataReady(args.CmdData);
DataReady(obj);
}