Walkthrough: Receiving Events in C/SIDE

Microsoft Dynamics Nav 2009

In the following walkthrough, you enable C/SIDE to receive events from the Dynamics NAV Communication Component. The Dynamics NAV Communication Component and the bus adapter are installed as part of the NAV Application Server. These two components must be installed before you can implement the following example.

C/SIDE can receive events from the components (automation servers and OCXs) that it controls. When you declare a global variable of data type Automation, you can specify whether you want to receive events. You do so by setting the WithEvents property for the variable to Yes. This automatically generates AL triggers for the events that the component provides. A trigger name consists of the name of the automation variable followed by "::<Event name>." For example, if you declare an automation variable with the name MyEventVar, and the component provides the event MessageReceived(...), the name of the trigger is MyEventVar::MessageReceived(...).

To complete this walkthrough, you will need:

In the following example, you create two codeunits: one that enables C/SIDE to receive an event – notification of an inbound stream, and one that enables the client to send the stream. In a real life situation the same client would not both send and receive the stream.

To send and receive streams, C/SIDE depends on the existence of two external components, the Dynamics NAV Communication Component and a socket bus adapter.

In this example you begin by creating the codeunit that allows the client to receive the event.

To create a codeunit and declare the variables

  1. In Object Designer, click Codeunit, and then click the New button.

  2. Click View, and then click C/AL Globals.

  3. In the C/AL Globals window, enter CC2 as the name of the first variable.

  4. In the Data Type field, select Automation.

  5. In the Subtype field, click the AssistButton to open the Automation Object List window.

  6. In the Automation Server field, click the AssistButton to open the Automation Server List window.

  7. In the Automation Server List window, select Dynamics NAV Communication Component version 2, and then click OK.The classes of the Dynamics NAV Communication Component are now visible in the Automation Object List window.

  8. Select the class called CommunicationComponent.

  9. Repeat steps 3 to 8 to declare the following variables.

    Variable name Data type Subtype

    SBA

    Automation

    Dynamics NAV Socket Bus Adaptor.SocketBusAdapter

    InMsg

    Automation

    Dynamics NAV Communication Component version 2.InMessage

    InS

    InStream

    txt

    Text

  10. Save the codeunit.

Now that you have declared the variables for the Dynamics NAV Communication Component and a bus adapter, you must set the WithEvents property for the Dynamics NAV Communication Component to Yes. By doing so, you subscribe to events from the Dynamics NAV Communication Component. This means that C/SIDE can receive notification of any inbound streams.

To set the WithEvents property

  1. Open the C/AL Globals window for this codeunit and select the variable CC2 that you created earlier.

  2. Open the Properties window, click the AssistButton in the Value field of the WithEvents property, and then select Yes.Setting the WithEvents property to Yes automatically creates a trigger in the codeunit for each event that the selected subtype of the global variable provides. In the case of the Dynamics NAV Communication Component, it creates the following trigger. CC2::MessageReceived(VAR InMessage : Automation "''_IDISPATCH")

Creating the Automation Servers

Before you can use the Dynamics NAV Communication Component and a bus adapter, you have to create instances of them. To do this, you use the C/AL function CREATE. To call CREATE, enter the following code in the OnRun trigger of the codeunit.

IF ISCLEAR(CC2) THEN

CREATE(CC2);

IF ISCLEAR(SBA) THEN

CREATE(SBA);

CC2.AddBusAdapter(SBA, 0);

SBA.OpenSocket(8079, ' ');

This code creates an instance of the Dynamics NAV Communication Component and a bus adapter. The bus adapter now uses port 8079 on the local computer.

Writing Code in the Trigger

The next step is to write the code in the MessageReceived trigger that determines what happens when the event occurs. Enter the following code in the MessageReceived trigger.

InMsg := InMessage;

InS := InMsg.GetStream();

WHILE NOT (InS.EOS) DO

BEGIN

InS.READ(txt);

MESSAGE(txt);

END;

InMsg.CommitMessage();

This code locates the input stream and uses the InStream.EOS function to determine whether the input stream has reached the End of Stream (EOS). It then uses the InStream.READ function to read the InStream object. The data is read in binary format. Finally, the code displays the text from the InStream in a message. The InStream.READ function has an optional parameter: InStream.Read(Variable, [Length]), that allows you to specify the number of bytes that you want to read from an InStream object. Save and compile the codeunit.

NoteNote

If you delete a global variable to which event triggers are associated, the event triggers and the code they contain are also deleted. Furthermore, if you change the Data Type or Subtype of a global variable, all the event triggers associated with this variable and their code is deleted.

When you have enabled C/SIDE to receive events from a component that it controls, for example, an automation server, you should be aware of the following limitations and restrictions. This information is also relevant for component developers. There are certain limitations on the triggers that are automatically generated for the events, which the component provides. Furthermore, incoming data is also subject to certain restrictions.

Limitations on Triggers

The following limitations exist on triggers that are automatically generated for the events:

  • C/SIDE only supports the default outgoing interfaces, that is, the source interfaces, which are defined by the automation variable. If more than one outgoing interface is defined by the automation server for a class, only event triggers for the default outgoing interface are generated in the C/AL code.

  • Function calls can have a maximum of 39 parameters.

  • Prototype text strings for functions can contain a maximum of 1024 characters.

  • The connectable object strategy in COM is used to connect Microsoft Dynamics NAV and the automation server. The Sink object defined in this strategy and implemented in Microsoft Dynamics NAV only supports the IDispatch interface (and IUnknown). It is therefore expected that the automation server calls on IDispatch when executing events.

  • Parameter names are truncated to a maximum of 30 characters.

  • There are no return values on event triggers.

  • The variable name along with "::" and the event trigger name are truncated to a maximum of 30 characters.

Restrictions on Incoming Data

All received data is copied to an internal data type, which can handle any data type that COM allows. No data is lost in this conversion and there is no check for valid C/AL data types. The data remains in this internal data type until it is used inside the trigger. When the data is used, it is converted to the appropriate C/AL data type.

However, if the data type is Variant, no conversion occurs. No data is lost in the conversion and all the required checks are made.

If the conversion cannot be performed successfully, because there is an invalid data type or because the data is outside the range, the event trigger causes an error message to be displayed and terminates execution. If the data is never used in the event trigger, no checks are performed for valid data, data type, and data range.

If a parameter is a VAR parameter (called ByRef) and the data is used inside the event trigger, there is an implicit conversion just before the event trigger returns. A check is made to see if the conversion can be performed. If the conversion cannot be performed, an error message is shown and the event trigger terminates.

Sending the Stream

The next step in this example is to create the codeunit that sends the stream.

To send the stream

  1. In Object Designer, click Codeunit, and then click the New button.

  2. Declare the following variables using the C/AL Globals window.

    Variable name Data type Subtype

    CC2

    Automation

    Dynamics NAV Communication Component version 2.CommunicationComponent

    SBA

    Automation

    Dynamics NAV Socket Bus Adaptor.SocketBusAdapter

    OutMsg

    Automation

    Dynamics NAV Communication Component version 2.OutMessage

    outS

    InStream

  3. In the C/AL Editor for the current codeunit, add the following lines of code to the OnRun trigger.

    IF ISCLEAR(CC2) THEN
        CREATE(CC2);
      IF ISCLEAR(SBA) THEN
        CREATE(SBA);
    CC2.AddBusAdapter(SBA, 0);
    OutMsg := CC2.CreateoutMessage('Sockets://localhost:8079');
    OutS := OutMsg.GetStream();
    OutS := WRITE('Hello world');
    OutS := WRITE('Using my first');
    OutS := WRITE('NAV Socket bus adapter');
    
  4. Save and compile the codeunit.

This code creates an instance of the Dynamics NAV Communication Component and a bus adapter. It then creates the OutMessage. If the OutMessage cannot be created it returns NULL.

The ICommunicationComponent::CreateOutMessage function has a destination parameter. This parameter has the following syntax.

Bus adapter type://destination

For example:

Named pipe://myServer/myPipe

Sockets://myserver::portnumber

Message queue://MyMessageQueueServer\MyQueue

The socket bus adapter is used to send the OutMessage to Port 8097. The text of the OutMessage is then specified.

Running and Testing the Example

The last step in this example is to test the codeunits that you have just created.

To run and test the example

  1. Start a Microsoft Dynamics NAV client and open the database that contains the codeunits that you have just created.

  2. In Object Designer, select the codeunit that receives the stream, and then click Run. This is a single instance codeunit and is therefore loaded into memory and stored there.

  3. Start another Microsoft Dynamics NAV client and open the same database.

  4. In Object Designer, select the codeunit that sends the stream, and then click Run.

  5. Switch back to the first client and you should see that it is receiving the stream and displaying the text that you defined earlier in the codeunit that sends the stream.

Community Additions

ADD
Show: