System of bus messages -- question on setup

72 views
Skip to first unread message

Bill M

unread,
Nov 16, 2015, 11:32:28 AM11/16/15
to FlatBuffers

I am evaluating using Flat Buffers on a project where I have need for a message bus between processes (Nanomsg).
There are many types of messages on the bus.  Those that need certain data can grab it.

What I am trying to figure out is the best way to map it.
With the root_type table, I can map a series of items and use the (id:) to help match them up.
I can have a message type filed that would help on the decode.

The main question is, should the main table have a content field that would be a union of structures for the various types of message?

So, if I have
enum MessageType: byte { None = 0,
                                        Msg1 = 1,
                                        ...
                                        Msg10 = 10,
                                        }

table Msg1Struct
{
    var1: short;
    var2: long;
}

table Msg2Struct
{
     var3: bool;
     var4: float;
}

... the reset of the tables

union Message { Msg1Struct, Msg2Struct, ....}

table MessageBus
{
    MsgType:MessageType (id:0);
    Packet: Message          (id:1);
}

root_type MessageBus

Would this work that if a task receives a message, it looks at MsgType to cast the Packet structure and
each table type would be serialized properly?

Flat Buffers has worked well on some simpler case project work, but I'm trying to figure out the best way to handle the more complex setup.

A big thank you to whoever can help on this topic.

Thanks!

mikkelfj

unread,
Nov 16, 2015, 1:18:52 PM11/16/15
to FlatBuffers
The idea is right, but you should not create the MessageType enum. The union creates it automatically with the table name as the enum name.
The type field is also created automatically. In fact, it is an error to create a field with an id one lower than the unions id because it is reserved for the type field.

Depending on the target language there are access methods to get the type first, then cast the message to the appropriate table.
If you look at generated code, it looks a bit like what you do, but don't do it in the schema.

Bill M

unread,
Nov 16, 2015, 3:11:05 PM11/16/15
to FlatBuffers
OK Thank you.

Target language is CPP and Go Lang.
I did see the packet type gets created in the code, so yes, this would provide the same function.
The main idea was to see what you got and then go about decoding it.
Each application may have a number of items it cares about and trigger events off the hander.
Anything else kind of hits the bit bucket in the default case.

I am now looking at how to construct it.  Looks like I work from two FlatBufferBulders.
Working on some code now....

Bill McCroskey

unread,
Nov 16, 2015, 8:30:31 PM11/16/15
to FlatBuffers
On 11/16/2015 03:11 PM, Bill M wrote:
Getting a bit hung up on the code of how to move a constructed sub table into the union and into the root table.
I will work on it more tomorrow and post an example of where I am stuck if needed.
Working on the C++ code in a simple sample test.


--
You received this message because you are subscribed to a topic in the Google Groups "FlatBuffers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/flatbuffers/xY45lsOVeOQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to flatbuffers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Bill M

unread,
Nov 17, 2015, 11:11:57 AM11/17/15
to FlatBuffers
Here is some example code where the schemas compile as does the code, but the transfer does not work.

Writing:
    FlatBufferBuilder fbb;
    FlatBufferBuilder fbbpkt;



    /* Construct a builder for the specific data channel */
    MessageBusBuilder mq(fbb);
    Msg1StructBuilder mqp(fbbpkt);

    mqp.add_var1(5);
    mqp.add_var2(1024);

    auto Packet = mqp.Finish();

    mq.add_Packet(Packet.Union());
    mq.add_Packet_type(Messages_Msg1Struct);
    auto mloc = mq.Finish();
    /* Finish the FlatBuffer builder buffer */
    FinishMessageBusBuffer(fbb, mloc);

That code compiles with no errors.

Reading:
    int bytes;

    void *buffer = NULL;

    bytes = nn_recv(PipeMsg, &buffer, NN_MSG, NN_DONTWAIT);

    if (bytes > 0)
    {
        auto MessageBuf = GetMessageBus(buffer);

        if (MessageBuf->Packet_type() == Messages_Msg1Struct)
        {
            auto Packet = reinterpret_cast<const Msg1Struct *>(MessageBuf->Packet());
            printf("Msg1 Var1 = %d\n", Packet->var1());
            printf("Msg1 Var2 = %lld\n", Packet->var2());
        }
        nn_freemsg(buffer);
    }

This also compiles and runs, but the variables show zero and not the loaded values.

I am not sure if I am handling the union correctly.


Bill M

unread,
Nov 18, 2015, 11:18:23 AM11/18/15
to FlatBuffers
I found the problem!

Only use one builder, so the code below changes to:


On Tuesday, November 17, 2015 at 11:11:57 AM UTC-5, Bill M wrote:
Here is some example code where the schemas compile as does the code, but the transfer does not work.

Writing:
    FlatBufferBuilder fbb;



    /* Construct a builder for the specific data channel */
    MessageBusBuilder mq(fbb);
    Msg1StructBuilder mqp(fbb);


    mqp.add_var1(5);
    mqp.add_var2(1024);

    auto Packet = mqp.Finish();

    mq.add_Packet(Packet.Union());
    mq.add_Packet_type(Messages_Msg1Struct);
    auto mloc = mq.Finish();
    /* Finish the FlatBuffer builder buffer */
    FinishMessageBusBuffer(fbb, mloc);

That code compiles with no errors.

Reading:
    int bytes;

    void *buffer = NULL;

    bytes = nn_recv(PipeMsg, &buffer, NN_MSG, NN_DONTWAIT);

    if (bytes > 0)
    {
        auto MessageBuf = GetMessageBus(buffer);

        if (MessageBuf->Packet_type() == Messages_Msg1Struct)
        {
            auto Packet = reinterpret_cast<const Msg1Struct *>(MessageBuf->Packet());
            printf("Msg1 Var1 = %d\n", Packet->var1());
            printf("Msg1 Var2 = %lld\n", Packet->var2());
        }
        nn_freemsg(buffer);
    }

This works properly.
 

Wouter van Oortmerssen

unread,
Nov 20, 2015, 3:43:57 PM11/20/15
to Bill M, FlatBuffers
Yes, you had one buffer refer to another. Sadly there's no easy way to detect that, as they're all integer offsets.

--
You received this message because you are subscribed to the Google Groups "FlatBuffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages