Table of Contents
- Introduction
- Prerequisites
- Setting Up
- Creating an MQTT Server
- Connecting to the MQTT Server
- Publishing and Subscribing
-
Introduction
In this tutorial, we will learn how to develop an IoT server using Go and MQTT (Message Queuing Telemetry Transport). MQTT is a lightweight messaging protocol commonly used for IoT applications. By the end of this tutorial, you will have a basic understanding of how to set up an MQTT server, connect clients to the server, and publish/subscribe messages.
Prerequisites
Before starting this tutorial, you should have the following:
- Basic knowledge of Go programming language
- Go installed on your machine
- MQTT client library for Go (e.g., paho.mqtt.golang)
Setting Up
To begin, let’s create a new Go project by following these steps:
- Create a new directory for your project:
mkdir iot-server
-
Change into the project directory:
cd iot-server
-
Initialize a Go module:
go mod init github.com/your-username/iot-server
Make sure you replace
github.com/your-username/iot-server
with your own project’s repository URL.Next, let’s add the MQTT client library to our project using the following command:
go get github.com/eclipse/paho.mqtt.golang
This will download and install the MQTT client library in your project’s
go.mod
file.
Creating an MQTT Server
Now that we have our project set up, let’s create an MQTT server using the following code:
package main
import (
"fmt"
"log"
"net"
"os"
"os/signal"
"syscall"
MQTT "github.com/eclipse/paho.mqtt.golang"
)
func main() {
opts := MQTT.NewServerOptions()
opts.DefaultPublishHandler = messageHandler
server := MQTT.NewServer(opts)
listener, err := net.Listen("tcp", ":1883")
if err != nil {
log.Fatal(err)
}
fmt.Println("MQTT server listening on :1883")
go func() {
if err := server.Start(listener); err != nil {
log.Fatal(err)
}
}()
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
<-signalCh
fmt.Println("Shutting down MQTT server...")
server.Stop()
listener.Close()
fmt.Println("Server stopped.")
}
func messageHandler(client MQTT.Client, msg MQTT.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
In the above code, we import the necessary packages and define a main
function. We create MQTT server options and set a default publish handler function called messageHandler
. This function will be called whenever a message is published to our MQTT server.
We then create the MQTT server using the options and start listening for incoming connections on port 1883. We also handle OS signals to gracefully shutdown the server when needed.
The messageHandler
function simply prints the received message and the associated topic. You can customize this function based on your requirements.
Save the code in a file named mqtt_server.go
.
Connecting to the MQTT Server
Now, let’s connect to the MQTT server from a client application using the following code:
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
MQTT "github.com/eclipse/paho.mqtt.golang"
)
func main() {
opts := MQTT.NewClientOptions().AddBroker("tcp://localhost:1883")
opts.SetClientID("mqtt-client")
opts.SetDefaultPublishHandler(messageHandler)
client := MQTT.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
log.Fatal(token.Error())
}
fmt.Println("Connected to MQTT server.")
topic := "home/temperature"
client.Subscribe(topic, 0, nil)
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
<-signalCh
fmt.Println("Disconnecting from MQTT server...")
client.Disconnect(250)
fmt.Println("Client disconnected.")
}
func messageHandler(client MQTT.Client, msg MQTT.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
In the above code, we import the necessary packages and define a main
function. We create MQTT client options, specify the server’s address (tcp://localhost:1883
), and set a client ID. We also set the default publish handler to messageHandler
, which will be called whenever a message is received.
We then create the MQTT client using the options and connect to the server. If the connection is successful, we print a confirmation message.
Next, we subscribe to the topic home/temperature
with a QoS (Quality of Service) level of 0.
Finally, we handle OS signals to gracefully disconnect from the server when needed.
Save the code in a file named mqtt_client.go
.
Publishing and Subscribing
To test the MQTT server and client, let’s publish and subscribe to messages.
In mqtt_server.go
, add the following lines of code before the server shutdown logic:
func main() {
// ...
go func() {
ticker := time.NewTicker(5 * time.Second)
for range ticker.C {
publishMessage("home/temperature", "25.5")
}
}()
// ...
}
func publishMessage(topic, payload string) {
opts := MQTT.NewClientOptions().AddBroker("tcp://localhost:1883")
client := MQTT.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
log.Fatal(token.Error())
}
defer client.Disconnect(250)
token := client.Publish(topic, 0, false, payload)
token.Wait()
if token.Error() != nil {
log.Println(token.Error())
} else {
fmt.Printf("Published message: %s to topic: %s\n", payload, topic)
}
}
In the code above, we’ve added a goroutine that publishes a message to the topic home/temperature
every 5 seconds. The publishMessage
function handles the connection, message publishing, and printing of a confirmation message.
To subscribe to the messages, update mqtt_client.go
as follows:
func main() {
// ...
go func() {
ticker := time.NewTicker(5 * time.Second)
for range ticker.C {
client.Subscribe("home/temperature", 0, nil)
}
}()
// ...
}
Now, when you run the MQTT server and client simultaneously, you should see the published messages being received and printed by the client.
Conclusion
In this tutorial, we learned how to develop an IoT server using Go and MQTT. We set up an MQTT server and a client, connected them, and published/subscribed to messages. This provides a basic foundation for building more complex IoT applications.
By following this tutorial, you should now be familiar with setting up an MQTT server in Go, connecting clients to the server, and handling message publishing/subscribing. You can further explore the MQTT protocol and library documentation to leverage more features and build scalable IoT applications.
Remember to use proper error handling and secure your MQTT server when deploying it in production environments. Happy coding!
Note: The code provided in this tutorial is for educational purposes only and may not be suitable for production environments without additional modifications and security measures.