简体   繁体   中英

golang dbus server example

Golang dbus module has provided the following example but it is not clear how the server receives a message and respond. A ping/pong example is appreciated:

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 {}
}

(This is just my impression from reading the program and the docs. Test for yourself to see if this is accurate)

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.

The program passes f of type foo to conn.Export .

foo has this method which matches the pattern described:

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

The response is the return values from this function not including the final error, ie, string(f) . ( "Bar!" in this case).

The empty select statement select {} at the end is a clever trick that I have never seen before. It is simply a statement that block forever. You can read more about it in this question . It's being used here simply to stop the main goroutine from terminating. In Go, the entire process will immediately end when the main goroutine finishes.

Given that this empty select is a "clever trick", it's probably better form to accompany it with a simple comment explaining:

// Blocks forever
select {}

Probably the reason why this example is confusing is because this Export method is quite magical. It takes a vaguely named empty interface value and figures out what to do with it based on some internal process that likely uses reflection. Unless you read the documentation for the function it's hard to guess what it'll do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM