go - golang dbus 服务器示例
问题描述
Golang dbus 模块提供了以下示例,但不清楚服务器如何接收消息并响应。一个 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
如果接收到对给定路径和接口的方法调用,如果参数匹配并且最后返回值的类型为 *Error,则以 v 作为接收者调用具有相同名称的导出方法。如果此 *Error 不为零,则将其作为错误发送回调用者。否则,将使用其他返回值作为其主体发送方法回复。
程序将f
类型传递foo
到conn.Export
.
foo
具有与描述的模式匹配的此方法:
func (f foo) Foo() (string, *dbus.Error)
响应是此函数的返回值,不包括最终错误,即string(f)
. ("Bar!"
在这种情况下)。
最后空的 select 语句select {}
是我以前从未见过的巧妙技巧。它只是一个永远阻塞的语句。您可以在这个问题中阅读更多相关信息。它在这里只是用来阻止main
goroutine 终止。在 Go 中,当主 goroutine 完成时,整个过程将立即结束。
鉴于这个空选择是一个“聪明的把戏”,最好用一个简单的注释来解释它:
// Blocks forever
select {}
可能这个例子让人困惑的原因是因为这个Export
方法非常神奇。它采用一个名称模糊的空接口值,并根据可能使用反射的一些内部过程来计算如何处理它。除非您阅读该函数的文档,否则很难猜出它会做什么。
推荐阅读
- geolocation - 是否有可能来自同一网络的 3 个 IP 地址来自不同的国家?
- android - 如何将投射按钮实现为浮动操作按钮?
- sql - ORA-00936: 缺少使用提示的表达式
- javascript - 如何对 AWS 托管后端进行 HTTPS 调用
- javascript - Firebase - 获取最后一个子 Javascript 的第一个值
- java - javaFx应用程序需要圆形滑块
- python - Flask Caching 文件系统缓存是否跨进程共享?
- python - 在xml,Python中使用if条件嵌套for循环
- javascript - 标准输出中的NodeJS child_process ansi
- node.js - 通过在猫鼬中不使用填充进行分组