我编写了以下 golang 程序作为
main.go
来学习 Go 中的 dbus :
package main
import (
"fmt"
"github.com/godbus/dbus/v5"
"time"
)
// Listener function to listen for D-Bus signals
func runListener() {
// Create a new D-Bus connection for the listener
conn, err := dbus.SessionBus()
if err != nil {
fmt.Println("Listener: Failed to connect to session bus:", err)
return
}
defer conn.Close()
// Request a unique name for the listener
busName := "org.example.Listener"
if _, reqErr := conn.RequestName(busName, dbus.NameFlagDoNotQueue); reqErr != nil {
fmt.Println("Listener: Failed to request name:", reqErr)
return
}
fmt.Println("Listener: Listening for messages on", busName)
// Add a match rule for the specific signal
err = conn.AddMatchSignal(
dbus.WithMatchInterface("org.example.ListenerInterface"), // Match interface
dbus.WithMatchMember("Message"), // Match signal member
)
if err != nil {
fmt.Println("Listener: Failed to add match rule:", err)
return
}
// Create a channel to receive signals
c := make(chan *dbus.Signal, 10)
conn.Signal(c)
// Listen for messages
fmt.Println("Listener: Waiting for D-Bus messages...")
for signal := range c {
fmt.Printf("Listener: Received message: %v\n", signal.Body)
}
}
// Sender function to send a D-Bus signal
func runSender() {
// Wait briefly to ensure the listener is ready
time.Sleep(2 * time.Second)
// Create a new D-Bus connection for the sender
conn, err := dbus.SessionBus()
if err != nil {
fmt.Println("Sender: Failed to connect to session bus:", err)
return
}
defer conn.Close()
// Define the signal details
objectPath := dbus.ObjectPath("/org/example/Listener") // Convert string to ObjectPath
interfaceName := "org.example.ListenerInterface"
signalName := interfaceName + ".Message"
// Emit the signal
fmt.Println("Sender: Sending message to listener...")
err = conn.Emit(objectPath, signalName, "Hello from the sender!")
if err != nil {
fmt.Println("Sender: Failed to send message:", err)
return
}
fmt.Println("Sender: Message sent successfully!")
}
func main() {
// Run the listener and sender as separate goroutines
go runListener()
go runSender()
// Prevent the program from exiting immediately
select {}
}
我遇到的问题是程序成功输出:
Listener: Listening for messages on org.example.Listener Listener:
Waiting for D-Bus messages... Sender: Sending message to listener...
Sender: Message sent successfully!
但请注意,没有“Listener:已收到消息”输出...
我还尝试使用两个单独的项目目录(监听器、发送器)中的两个单独的
main.go
文件来执行此操作,但我无法正确配置 GoLand 以同时运行这两个 main.go
文件,因为我得到了来自 GoLand 的错误:package dbus_messenger is not in std (/usr/lib/golang/src/dbus_messenger)
。
只需更改您的代码即可使用ConnectSessionBus。
SessionBus使用共享连接,可能会干扰消息接收。
SessionBus 返回一个到会话总线的共享连接,连接 如果还没有完成的话。
通过此更改,您的代码可以正常工作。
go run main.go
Listener: Listening for messages on org.example.Listener
Listener: Waiting for D-Bus messages...
Sender: Sending message to listener...
Sender: Message sent successfully!
Listener: Received message: [Hello from the sender!]
它也可以使用
dbus-send
dbus-send --session \
--dest=org.example.Listener \
--type=signal \
/org/example/Listener \
org.example.ListenerInterface.Message \
string:"Hello from dbus-send!"