This example code shows how to dump the currently configured attributes of a context and 2 different sources.
When reading the documentation below, click on any line number to display the pure source listing on the right side of the screen. Similarly, if you click on a line number on the right side of the screen, the corresponding documentation will be displayed on the left.
There is one program source file:
The example source code is organized as a .NET class.
The first phase of any UM program is initialization, where UM objects are created. The first object to be created is a UM context object:
00027 /* create ctxAttr to set config values before creating context */ 00028 LBMContextAttributes ctxAttr = new LBMContextAttributes(); 00029 ctxAttr.setObjectRecycler(objRec, null); 00030 00031 /* Modify resolver address by setting attributes */ 00032 ctxAttr.setValue("resolver_multicast_address", "224.10.11.12"); 00033 00034 /* Create a context with default attributes */ 00035 ctx = new LBMContext(ctxAttr);
A context can be thought of as an "instance" of UM. It contains a worker thread which maintains internal state and reacts to socket events. Most UM applications create a single context instance which manages the publishing and receiving of messages over many topics, although there are less-common use cases which call for multiple context instances within a single process (see TODO).
The next object that needs to be created is a "source" object. Creation of a source object is a two-step procedure: first create a "topic" object, specifying the topic name, and then create the "source" object, which is the object used subsequently to send messages.
00036 /* Create source attributes object, used to configure sources */ 00037 srcAttr = new LBMSourceAttributes(); 00038 srcAttr.setObjectRecycler(objRec, null); 00039 00040 /* Set configuration value using strings */ 00041 srcAttr.setValue("transport", "lbtrm"); 00042 00043 /* The Java API only accepts string values. ints, for example */ 00044 /* must be converted to strings */ 00045 desPort = 14001; 00046 srcAttr.setValue("transport_lbtrm_destination_port", desPort.ToString()); 00047 00048 /* Create topic for the first source with configured attributes */ 00049 topic1 = new LBMTopic(ctx, "test.topic1", srcAttr); 00050 src1 = new LBMSource(ctx, topic1);
In this example, a second source is created. The only difference between between the 2 sources created in this example is that they are configured to use different destination ports. This will enable the user to view differences in the attributes that will be dumped later.
00051 /* Modify Configuration for second topic to use a new port */ 00052 desPort = 14002; 00053 srcAttr.setValue("transport_lbtrm_destination_port", desPort.ToString()); 00054 00055 /* Create second topic and source using modified configuration values */ 00056 topic2 = new LBMTopic(ctx, "test.topic2", srcAttr); 00057 src2 = new LBMSource(ctx, topic2);
In this block, we will dump every attribute that the context object is configured to use. Many of these values are expected to be default. This is because only the resolver_multicast_address was set to a non-default value in the beginning of this example program. In a non-trivial application, it is common for many of the default attributes to be overridden by a configuration file, xml file, or programatically.
00064 System.Console.Out.WriteLine("Context Attributes: "); 00065 List<LBMConfigOption> cfgOptList = ctx.dumpAttributeList(); 00066 for (int i = 0; i < cfgOptList.Count; i++) 00067 { 00068 System.Console.Out.WriteLine(cfgOptList[i].Type + " " + cfgOptList[i].OptionName + " " + cfgOptList[i].Value); 00069 }
In this block, we will dump every attribute that the first source object is configured to use. Many of these values are expected to be default. This source is configured to use a non-default transport and transport_lbtrm_destination_port. These values can be seen the console output of this applciation.
00070 System.Console.Out.WriteLine("Source #1 Attributes: "); 00071 cfgOptList = src1.dumpAttributeList(); 00072 for (int i = 0; i < cfgOptList.Count; i++) 00073 { 00074 System.Console.Out.WriteLine(cfgOptList[i].Type + " " + cfgOptList[i].OptionName + " " + cfgOptList[i].Value); 00075 } next ref last ref
Here, the second source's attributes will be dumped. The only difference between the two sources in this example is the transport_lbtrm_destination_port. This can be viewed in the console output of the example application.
00070 System.Console.Out.WriteLine("Source #1 Attributes: "); 00071 cfgOptList = src1.dumpAttributeList(); 00072 for (int i = 0; i < cfgOptList.Count; i++) 00073 { 00074 System.Console.Out.WriteLine(cfgOptList[i].Type + " " + cfgOptList[i].OptionName + " " + cfgOptList[i].Value); 00075 } first ref prev ref
This block contains the code necessary to clean up the remaining lbm objects. Unlike most common practices in .NET, most UM objects should be explicitly closed when they are no longer needed. Since most UM objects contain an active component, just letting them go out of scope to be garbage collected is not an appropriate way to dispose of them. Note that the srcAttr oject does not have a close method. In order to close this object, it can be tied to an "object recycler, as was done on srcAttr's constructor. This will allow the recycler clean up the ojbect when the recyclers .close method is called.
When deleting UM objects, order of deletion is important:
00085 objRec.close(); 00086 src2.close(); 00087 src1.close(); 00088 ctx.close();
In general, timers should be cancelled first. Then source and receiver objects should be deleted, then context objects, and lastly event queues. These object deletions can become somewhat complex if event queues are used; see TODO for more explanation.
licensing: TODO
configuration: TODO
anything else? TODO