Giter Club home page Giter Club logo

publish-to-rabbitmq-in-c's Introduction

Publish to RabbitMQ With C

The purpose of this example is quick & dirty. It's meant to serve as a low-level example on how to establish a tcp connection to a local RabbitMQ server, perform the handshake, publish a message to a pre-existing queue, and then shut down the connection gracefully.

I wrote this as a guide for writing embedded logic on a microcontroller. That microcontroller only needs to "report" on a status when it changes, aka an alert.

My goal was not elegance. My goal was to create an MVP (minimally viable product) that is purely a learning tool...so yes, there is repeated code and its not as clean as it could be.

My Environment

I am running a RabbitMQ server on a local Docker container. The rabbitmq/3-management image, to be precise.

Default Rabbit MQ setup:

  • Port 5672
  • Username guest
  • Password guest
  • Virtual Host /

I created a queue named, lee.test.q.

I am using CMake as my build utility but it's a bit of overkill for this. (That and I'm getting used to CMake)

My files:

  1. program.c
    • The main program lives here. So does virtually all of the code.
  2. program.h
    • The header file. Includes, some defines and some structure definitions for the most part. I also included some function prototypes for visibility.
  3. converters.c
    • When playing with arrays of bytes, sometimes you have to extract out short and integer numbers. I have some conversion routines in here to help me out.

Specs

I had to do a lot of pouring over AMQP specifications and cross-referencing things because they just weren't clear enough for me, right off the bat. RabbitMQ has some nice documentation on the various AMQP methods I needed but to really track down the details of the data structures and values, I had to use the XML specification.

The Job

The job that this code performs is to publish the message, "Hello, there!" to the lee.test.q queue on my local RabbitMQ server. I foolishly thought it was a simple matter of opening a TCP socket and pushing some bytes to it. Oh how naive that thought was!

Turns out, my steps were more along the lines of:

  1. Open a TCP socket to the server
  2. Push a Protocol message to get things started: {'A','M','Q','P',0,0,9,1}
  3. Get back a Start message
  4. Respond with a Start OK message
  5. Get a Tune message
  6. Respond with a Tune OK message
  7. Push an Open message
  8. Push a message to Open Channel for Channel 1.
    • Channel 0 is the system channel for things like establishing connections.
  9. Push a message that we want to Publish some content
  10. Push a Content Header that describes the content
  11. Push the Content, which for us is "Hello, there!"
  12. Push a Close connection message
  13. Shutdown our TCP socket.

Examining the RabbitMQ Logs

One of the nice things when troubleshooting socket communication is being able to see what is going on from both sides of the communication. I spent a lot of time just guessing what the server was seeing and how it was handling things. Those guesses led to wrong assumptions and a lot of headache/time wasted. Then Google came to the rescue with a nice little command for viewing a tail of the RabbitMQ server's logs!

docker logs localrabbit

Omg, this is helpful! Of course, I named my docker container to localrabbit so if you didn't do that, the command will be slightly different for you. It was telling me if the server was having difficulties parsing my messages (it was) and dumped the byte arrays for me. Normal AMQP specs state that if anything looks weird or wrong, just kill the connection. With these logs, I can now see why the server was killing my socket.

Thank You!

No work nor assistance should go unpunis....er, unrecognized. I'll freely admit that I was only able to get this done with a lot of help from others who have done better work than I.

  1. rabbitmq-c library.
    • This is a nice C library maintained by alanxz. If you are looking for a library for RabbitMQ communication, this is what you want!
  2. RabbitMQ .NET Client
    • I datamined this library for message structures when the specs failed me.
  3. AMQP-CPP
    • Another project I dug through for information.
  4. StackOverflow
    • I haven't messed with bits && bytes since before StackOverflow was born. Packing/Unpacking integers to bytes escaped me one afternoon. Thank you, StackOverflow!
  5. Google
    • I still remember what programming was like before there was Google. I don't want to go back to those days.

publish-to-rabbitmq-in-c's People

Contributors

spankr avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.