【问题标题】:golang dbus server examplegolang dbus 服务器示例
【发布时间】:2021-03-28 20:33:35
【问题描述】:

Golang dbus module 提供了以下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 {}
}

【问题讨论】:

    标签: go server dbus


    【解决方案1】:

    (这只是我阅读程序和文档的印象。您自己测试一下是否准确)

    https://pkg.go.dev/github.com/godbus/dbus#Conn.Export

    func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error
    

    如果接收到在给定路径和接口上的方法调用,如果参数匹配并且最后返回值的类型为 *Error,则以 v 作为接收者调用同名的导出方法。如果此 *Error 不为零,则将其作为错误发送回调用者。否则,以其他返回值作为正文发送方法回复。

    程序将foo 类型的f 传递给conn.Export

    foo 具有与描述的模式匹配的此方法:

    func (f foo) Foo() (string, *dbus.Error)
    

    响应是此函数的返回值,不包括最终错误,即string(f)。 (在这种情况下为"Bar!")。

    最后的空select语句select {}是一个我以前从未见过的聪明的把戏。它只是一个永远阻塞的语句。您可以在this question 中阅读有关它的更多信息。它在这里只是用来阻止main goroutine 终止。在 Go 中,当主 goroutine 完成时,整个过程将立即结束。

    鉴于这个空选择是一个“聪明的把戏”,最好的形式可能是附上一个简单的注释解释:

    // Blocks forever
    select {}
    

    这个例子之所以让人迷惑,大概是因为这个Export的方法相当神奇。它采用一个名称模糊的空接口值,并根据可能使用反射的一些内部过程来计算如何处理它。除非您阅读该函数的文档,否则很难猜出它会做什么。

    【讨论】:

    • 谢谢,这个方法被调用了。仍然不明白代码末尾的空select {}。我正在寻找来收听的频道。
    • 再次感谢。我是一个初学者,但不知何故对这个项目的设计决策不太满意,它是市场上唯一的一个。不能再投票了,但很快就会提出另一个问题。
    猜你喜欢
    • 2014-10-31
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2011-12-30
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    相关资源
    最近更新 更多