My favorite method of communication between processes-message bus


Brother Tao's 020 original

1. Inter-process communication (IPC) in Linux system

As an embedded software developer, it is very common to handle communication between processes . From the perspective of communication purpose , we can divide the communication between processes into three types:

  1. For process scheduling: it can be achieved through signals;
  2. In order to share resources: it can be achieved through mutual exclusion locks, semaphores, read-write locks, file locks, etc.;
  3. In order to transfer data: it can be implemented through shared memory, named pipes, message queues, and Sockets.

Regarding the communication primitives mentioned above, the operating system provides us with various materials and articles on the Internet, so I won’t be long-winded here. How should one choose among these methods? According to my personal experience, the preciousness is not too expensive , and careful selection of three or four things can fully meet the needs of daily work.

The issue we want to discuss today is mainly the third one: transferring data . Among the above several methods of transferring data, my favorite and most commonly used is Socket communication .

Some friends may say: Socket communication is the TCP/IP set of things, and it is also very troublesome to manage the connection, group and sub-package the data by yourself .

Yes, Socket communication itself does need to manually handle these low-level things, but we can put a "coat" on Socket: use the MQTT message bus to exchange data between the various processes of the system . Here we will one by one. Road come.

Second, the advantages of Socket-based communication

Here I will not play it by myself, and directly quote the views in the book "Linux Multithreaded Server Programming" by Mr. Chen Shuo (page 65, section 3.4):

1. Cross-host, with scalability

Anyway, there are multiple processes. If the processing power of one machine is not enough, multiple hosts can be used for processing. Distribute the process to multiple machines on the same LAN, and continue to use the program by changing the Host:Port configuration. On the contrary, the communication methods between the processes listed at the beginning of the article cannot be cross-machine, which limits scalability .

2. The operating system will automatically reclaim resources

The TCP port is exclusively owned by a process. When the program exits unexpectedly, the operating system will automatically reclaim resources without leaving garbage to the system, and it can be recovered relatively easily after the program is restarted.

3. Recordable and reproducible

The two processes communicate via TCP. If one crashes, the operating system will close the connection, and the other process can feel it almost immediately and failover quickly. Of course, the heartbeat of the application layer is essential. (Supplement: The operating system itself has a keep-alive time for TCP connections, the default is 2 hours, and it is global.)

4. Cross-language

The server and the client do not have to use the same programming language.

  1. Mr. Chen Shuo described general Socket communication, so the client and server are generally located on different physical machines.
  2. In embedded development, the same programming language is generally used, so the cross-language is somewhat negligible.

Three, MQTT message bus

1. MQTT is a communication mechanism

Small partners who are familiar with the Internet of Things must be very familiar with the MQTT message bus . At present, several major Internet of Things cloud platforms (Amazon, Alibaba Cloud, and Huawei Cloud) provide access to the MQTT protocol.

Currently, the best document for learning MQTT is IBM's online manual : https://developer.ibm.com/zh/technologies/messaging/articles/iot-mqtt-why-good-for-iot/.

Here, I directly list some key information :

  1. The MQTT protocol is lightweight, simple, open and easy to implement;
  2. MQTT is a message protocol based on Publish/Subscribe paradigm;
  3. MQTT works on the TCP/IP protocol suite;
  4. There are three types of message publishing service quality;
  5. Small transmission, low overhead (fixed-length header is 2 bytes), protocol exchange is minimized to reduce network traffic;

MQTT message transmission requires a middleware called Broker, which is actually a Server. The communication model is as follows:

  1. MQTT Broker needs to be started first;
  2. ClientA and ClientB need to connect to Broker;
  3. ClientA subscribes to topic topic_1, ClientB subscribes to topic topic_2;
  4. When ClientA sends a message to the topic topic_2, it will be received by ClientB;
  5. When ClientB sends a message to topic_1, it will be received by ClientA;

The topic-based communication method has a great advantage of decoupling . A client can subscribe to multiple topics , and any other client connected to the bus can send information to these topics (a client sends a message to itself it is also fine).

2. Implementation of MQTT

MQTT is just a protocol. As you can see in IBM's online documentation, there are many languages ​​that implement the MQTT protocol, including: C/C++, Java, Python, C#, JavaScript, Go, Objective-C, and so on. For embedded development, these implementations are more commonly used:

Mosquitto;
Paho MQTT;
wolfMQTT;
MQTTRoute

In the following, we will focus on the compilation and use of Mosquitto, an open source implementation, which is the one I use most in my projects.

3. On top of MQTT, design your own communication protocol

As can be seen from the above description, the MQTT message bus is just a communication mechanism that provides a channel for the communication subject to transfer data.

On this channel, we can send data in any format and encoding according to the needs of the actual project . In the project, the most commonly used is the plain text in json format, which is also the method recommended by various IoT cloud platforms. If binary data needs to be included in the text data, it will be converted to BASE64 encoding before sending.

Fourth, how to use the MQTT message bus in an embedded system

As can be seen from the above description, as long as an MQTT Broker service is running on the server side , each client connected to the bus can flexibly send and receive data to each other.

We can apply this mechanism to the design of embedded applications : MQTT Broker runs locally in the embedded system as an independent service , and other processes that need to interact, as long as they connect to the local Broker, they can send data to each other. The running model is as follows:

Each process only needs to subscribe to a fixed topic (for example: its own client Id), then if other processes want to send data to it, they can send it directly to this topic.

1. A communication framework for an embedded system

I have previously developed an environmental monitoring system that collects pollutant parameters such as PM2.5 and PM10 in the atmosphere. It is developed under the Contex A8 platform and needs to implement data recording (database), UI monitoring interface and other functions.

The pollutant data sampling hardware module is provided by a third-party company. We only need to control the sampling equipment and receive the sampling data through the serial port protocol provided by the module. The final designed communication model is as follows:

  1. The UI process sends control instructions to the sampling control process through the message bus, and the sampling control process sends control instructions to the sampling module through the serial port after receiving it;
  2. After the sampling control process receives PM2.5 and other data sent by the sampling module from the serial port, it sends all the data to the specified topic on the message bus;
  3. The UI process subscribes to the topic, and after receiving the data, it is displayed on the screen;
  4. The database process also subscribes to the topic and stores the data in the SQLite database after receiving the data;

In this product, the core process is the sampling control process , responsible for the interaction with the sampling module. By designing UI processing and database processing as independent processes, the complexity of the system is reduced. Even if these two processes crash, it will not affect the core sampling control process.

For example: if the UI process crashes due to an error, it will restart immediately. After startup, the cached information knows that sampling is being performed at the moment, so the UI process immediately connects to the message bus, enters the sampling data display interface, and continues to receive and display the data sent by the sampling control process. PM2.5 and other data .

This communication model has another advantage: scalability .

In the later stage of the project development, Party A said that it needs to integrate a third-party gas module to collect parameters such as NO and SO2 in the atmosphere. The communication method is RS485.

At this time, it is very simple to extend this functional module. Write an independent gas parameter process directly and connect it to the message bus . When this process receives NO, SO2 and other gas parameters from a third-party gas module via RS485, it is directly sent to a topic on the message bus, and the UI process and database process subscribe to this topic, you can immediately receive gas-related data Up.

In addition, this design model has some other advantages :

  1. Parallel development: each process can be developed in parallel by different people, as long as the communication protocol is defined between each other;
  2. Easy to debug: Since the data sent is all manual readable, in the development stage, you can write a special monitoring program on the PC and connect to the MQTT Broker in the embedded system, so that you can receive the messages sent by all processes;
  3. Communication security: After the product is released, in order to prevent others from eavesdropping on the data (such as the debugging process in 2), you can specify a configuration file for the MQTT Broker, and only allow the local process (127.0.0.1) to connect to the message bus.

2. A slightly more complicated communication model

In the embedded system framework design just described, each process runs locally , and all messages are sent and received within the system . So, if you need to transmit data to the cloud, or need to receive some control commands from the cloud, how to design it?

Just add a MQTT Bridge bridge module ! That is to add another process, this process is connected to the cloud MQTT Broker and the local MQTT Broker at the same time , the communication model is as follows:

  1. When MQTT Bridge receives an instruction from the cloud, it forwards it to the local message bus;
  2. When MQTT Bridge receives a local message, it forwards it to the message bus in the cloud.

Five, Mosquitto: a simple test code

The above content mainly discusses the idea of design. When it comes to the code level, I generally use the open source implementation of Mosquitto .

It is very convenient to install and test in the Linux system, and I will briefly explain it below.

1. Install and test directly through apt

You can refer to this document (https://www.vultr.com/docs/how-to-install-mosquitto-mqtt-broker-server-on-ubuntu-16-04) to install and test.

(1) Installation

sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt-get update
sudo apt-get install mosquitto
sudo apt-get install mosquitto-clients

(2) Test

mosquitto broker will after the installation to start automatically , you can use netstatto view the 1883 port to confirm.

Receiver : After connecting to the broker, subscribe to the topic "test".

mosquitto_sub -t "test"

Sender : After connecting to the broker, send the string "hello" to the topic "test".

mosquitto_pub -m "hello" -t "test"

When the sender executes mosquitto_pub, the string "hello" can be received in the terminal window of the receiver.

2. Manually compile and test through source code

Installation through apt is mainly used for simple learning and testing. If you want to use Mosquitto in project development, you must manually compile , get the header files and library files, and then copy them to the application.

(1) Manually compile and install Mosquitto

My development environment is:

  1. Compiler: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
  2. Mosquitto version: mosquitto-1.4.9

mosquitto-1.4.9 can be downloaded from the official website, or from the network disk at the end of the article, or you can try a higher version.

Compile and install instructions:

make
make install prefix=$PWD/install

After successful installation, you can see the output file in the install folder of the current directory :

  1. bin: mqtt client program;
  2. include: header files that the application needs to include;
  3. lib: the library file that the application needs to link;
  4. sbin: mqtt broker service program.

During the compilation process, if you encounter errors such as ares.h, uuid.h and other dependent files that cannot be found, you only need to install the corresponding development package through the apt command.

(2) The simplest mosquitto client code

In the mosquitto source code, a wealth of Sample examples are provided. If you are not willing to explore, you can directly download the Demo sample program in the online disk at the end of the article. After this program is connected to the message bus, subscribe to the topic "topic_01". Of course, you can also modify the code to send messages (call: mosquitto_publish this function).

After entering the c_mqtt sample code directory, you can see that the bin, include, and lib directories have been included, which are copied from the installation directory install in (1) above.

Execution makeafter the instruction, you can compile successfully obtain executable file: mqtt_client .

The test process is as follows:

Step1: Start MQTT Broker

In the first terminal window, start the Broker program sbin/mosquitto . If you have started a broker in the above test, you need to kill the previous broker first, because they all use port 1883 by default and cannot coexist.

Step2: Start the receiver program mqtt_client

In the second terminal window, start mqtt_clientis an executable program compiled our sample code to get in, it subscribed topic is "topic_01".

./mqtt_client 127.0.0.1 1883

Parameter 1: The IP address of the Broker service, because it is in the local system, so it is 127.0.0.1;
Parameter 2: The port number, generally the default is 1883.

Step3: Start the sender program bin/mosquitto_pub

In the third terminal window, start bin/mosquitto_pub, the command is as follows:

./mosquitto_pub -h 127.0.0.1 -p 1883 -m "hello123" -t "topic_01"

Parameter -h: Broker service IP address, because it is in the local system, so it is 127.0.0.1;
parameter -p: port number 1883;
parameter -m: message content sent;
parameter -t: topic topic sent.

At this point, you can print out the received message in the second terminal window (mqtt_client).

Six, summary

This article mainly introduces a design pattern in embedded systems: the communication between processes is realized through the message bus , and the open source implementation of Mosquitto is introduced.

In actual projects, stricter authority control is also required , such as: providing user name, password, device certificate when accessing the message bus, the name of the client must meet the specified format, and the subscribed topic must meet a certain format, etc. .

In the next article, we continue to discuss this topic and give a more specific and practical Demo routine.

Seven, resource download

1. mosquitto-1.4.9.tgz

Link: https://pan.baidu.com/s/1izQ3dAlGbHiHwDvKnOSfyg
Password: dozt

2. Mosquitto Demo sample code

Link: https://pan.baidu.com/s/1M-dU3xapNbKyk2w07MtDyw
Password: aup3


Don't brag, don't hype, don't exaggerate, write every article carefully!
Welcome to forward, to share to friends around technology, Columbia Road, to express my heartfelt thanks! Forwarded recommended language has helped you to think it over:

This summary article summarized by Brother Dao was written very carefully, which is very helpful to my technical improvement. Good things to share!


[Original Statement]

OF: Columbia Road (public No.: The IOT of town things )
know almost: Columbia Road
station B: Share Columbia Road
Denver: Columbia Road share
CSDN: Columbia Road Share

Reprint: Welcome to reprint, but without the consent of the author, this statement must be retained, and the original link must be given in the article.

Pay attention to the + star public account and don’t miss the latest article! [insert image description here](https://img-blog.csdnimg.cn/20210216135945474.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10, text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTIyOTYyNTM=,size_16,color_FFFFFF,t_70#pic_center)


Recommended reading

C language pointers-from the basic principles to fancy skills, with pictures and codes to help you explain thoroughly
step by step analysis-how to use C to implement object-oriented programming to
improve code forcing a powerful tool: macro definition-from entry to abandon the
original gdb bottom layer The debugging principle is so simple.
Use setjmp and longjmp in the C language to realize exception capture and coroutines
about encryption and certificates.
Deepen into the LUA scripting language, so that you can fully understand the principle of debugging.

Guess you like

Origin blog.csdn.net/u012296253/article/details/113824425