Problem description:
I am working on a small project in which i need to port the existing mqtt client library from Golang to Android. I found using gomobile repository as an option to prevent duplicating the same functionality in different programming languages (GO and Java).
To use this library we have two different options:
- Design the android app purely in Go and use "gomobile -build" to generate an APK file. An APK file then can be loaded to android device or emulator using adb tool.
- Implement some functionality and then bind them into existing Android project using "gomobile -bind". With this option there are some restriction for conversion and building Golang objects.
For my case I plan to pick the second option. Also trying to convert the following small sample GO implementation to Android (borrowed from here).
package main
import (
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"log"
"time"
)
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
fmt.Println("Connected")
}
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
fmt.Printf("Connect lost: %v", err)
}
func main() {
var broker = "broker.emqx.io"
var port = 1883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("go_mqtt_client")
opts.SetUsername("emqx")
opts.SetPassword("public")
opts.SetDefaultPublishHandler(messagePubHandler)
opts.OnConnect = connectHandler
opts.OnConnectionLost = connectLostHandler
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
sub(client)
publish(client)
client.Disconnect(250)
}
func publish(client mqtt.Client) {
num := 10
for i := 0; i < num; i++ {
text := fmt.Sprintf("Message %d", i)
token := client.Publish("topic/test", 0, false, text)
token.Wait()
time.Sleep(time.Second)
}
}
func sub(client mqtt.Client) {
topic := "topic/test"
token := client.Subscribe(topic, 1, nil)
token.Wait()
fmt.Printf("Subscribed to topic: %s", topic)
}
My Question:
After converting the sample code, i am not sure how i can implement the listener side. the probelm is that "gomobile -bind" cannot convert all user data types (i.e client into Java). I can implement the connect, subscribe, and publish, but not the listener one (in other words, the "opts.SetDefaultPublishHandler(messagePubHandler)" is not repeatedly working when i call the corresponding method in Android)
Any suggestion?
This is what is tried, but it does not work
var Options *mqtt.ClientOptions
var ReceivedMsg string
func AddBroker(broker string, port int) {
Options = mqtt.NewClientOptions()
Options.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
}
var MessagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
ReceivedMsg = " Message " + string(msg.Payload()) + " received on topic" + msg.Topic()
fmt.Printf(ReceivedMsg)
}
func Listener(clientId string) {
Options.SetClientID(clientId)
Options.SetDefaultPublishHandler(MessagePubHandler)
Options.OnConnect = ConnectHandler
Options.OnConnectionLost = ConnectionLostHandler
}