golang dbus 服务器示例
golang dbus server example
Golang dbus module has provided the following example但是不清楚服务端是如何接收消息和响应的。推荐一个 ping/pong 示例:
package main
import (
"fmt"
"os"
"github.com/godbus/dbus"
"github.com/godbus/dbus/introspect"
)
const intro = `
<node>
<interface name="com.github.guelfey.Demo">
<method name="Foo">
<arg direction="out" type="s"/>
</method>
</interface>` + introspect.IntrospectDataString + `</node> `
type foo string
func (f foo) Foo() (string, *dbus.Error) {
fmt.Println(f)
return string(f), nil
}
func main() {
conn, err := dbus.ConnectSessionBus()
if err != nil {
panic(err)
}
defer conn.Close()
f := foo("Bar!")
conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
conn.Export(introspect.Introspectable(intro), "/com/github/guelfey/Demo",
"org.freedesktop.DBus.Introspectable")
reply, err := conn.RequestName("com.github.guelfey.Demo",
dbus.NameFlagDoNotQueue)
if err != nil {
panic(err)
}
if reply != dbus.RequestNameReplyPrimaryOwner {
fmt.Fprintln(os.Stderr, "name already taken")
os.Exit(1)
}
fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
select {}
}
(这只是我阅读程序和文档的印象。自己测试一下是否准确)
https://pkg.go.dev/github.com/godbus/dbus#Conn.Export
func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error
If a method call on the given path and interface is received, an exported method with the same name is called with v as the receiver if the parameters match and the last return value is of type *Error. If this *Error is not nil, it is sent back to the caller as an error. Otherwise, a method reply is sent with the other return values as its body.
程序将 foo
类型的 f
传递给 conn.Export
。
foo
具有与描述的模式相匹配的方法:
func (f foo) Foo() (string, *dbus.Error)
响应是此函数的 return 值,不包括最终错误,即 string(f)
。 ("Bar!"
在这种情况下)。
最后的空select语句select {}
是我从未见过的巧妙技巧。它只是一个永远阻塞的语句。您可以在 this question 中阅读更多相关信息。它在这里只是用来阻止 main
goroutine 终止。在 Go 中,当 main goroutine 完成时,整个过程将立即结束。
鉴于这个空 select 是一个“聪明的把戏”,最好附上一条简单的评论解释:
// Blocks forever
select {}
这个例子之所以让人迷惑,大概是因为这个Export
方法比较神奇吧。它接受一个命名模糊的空接口值,并根据一些可能使用反射的内部过程来确定如何处理它。除非您阅读该函数的文档,否则很难猜测它会做什么。
Golang dbus module has provided the following example但是不清楚服务端是如何接收消息和响应的。推荐一个 ping/pong 示例:
package main
import (
"fmt"
"os"
"github.com/godbus/dbus"
"github.com/godbus/dbus/introspect"
)
const intro = `
<node>
<interface name="com.github.guelfey.Demo">
<method name="Foo">
<arg direction="out" type="s"/>
</method>
</interface>` + introspect.IntrospectDataString + `</node> `
type foo string
func (f foo) Foo() (string, *dbus.Error) {
fmt.Println(f)
return string(f), nil
}
func main() {
conn, err := dbus.ConnectSessionBus()
if err != nil {
panic(err)
}
defer conn.Close()
f := foo("Bar!")
conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
conn.Export(introspect.Introspectable(intro), "/com/github/guelfey/Demo",
"org.freedesktop.DBus.Introspectable")
reply, err := conn.RequestName("com.github.guelfey.Demo",
dbus.NameFlagDoNotQueue)
if err != nil {
panic(err)
}
if reply != dbus.RequestNameReplyPrimaryOwner {
fmt.Fprintln(os.Stderr, "name already taken")
os.Exit(1)
}
fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
select {}
}
(这只是我阅读程序和文档的印象。自己测试一下是否准确)
https://pkg.go.dev/github.com/godbus/dbus#Conn.Export
func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error
If a method call on the given path and interface is received, an exported method with the same name is called with v as the receiver if the parameters match and the last return value is of type *Error. If this *Error is not nil, it is sent back to the caller as an error. Otherwise, a method reply is sent with the other return values as its body.
程序将 foo
类型的 f
传递给 conn.Export
。
foo
具有与描述的模式相匹配的方法:
func (f foo) Foo() (string, *dbus.Error)
响应是此函数的 return 值,不包括最终错误,即 string(f)
。 ("Bar!"
在这种情况下)。
最后的空select语句select {}
是我从未见过的巧妙技巧。它只是一个永远阻塞的语句。您可以在 this question 中阅读更多相关信息。它在这里只是用来阻止 main
goroutine 终止。在 Go 中,当 main goroutine 完成时,整个过程将立即结束。
鉴于这个空 select 是一个“聪明的把戏”,最好附上一条简单的评论解释:
// Blocks forever
select {}
这个例子之所以让人迷惑,大概是因为这个Export
方法比较神奇吧。它接受一个命名模糊的空接口值,并根据一些可能使用反射的内部过程来确定如何处理它。除非您阅读该函数的文档,否则很难猜测它会做什么。