Home  >  Article  >  Backend Development  >  Error org.freedesktop.DBus.Error.UnknownMethod: Unknown/invalid method 'Notify'

Error org.freedesktop.DBus.Error.UnknownMethod: Unknown/invalid method 'Notify'

PHPz
PHPzforward
2024-02-06 08:00:171159browse

错误 org.freedesktop.DBus.Error.UnknownMethod:未知/无效方法“Notify”

Question content

I'm trying to create a notification server using godbus, but I can't export my server object to dbus properly, and dbus only Recognizes my introspection xml. I followed https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html to implement it. I'm also using _example/server.go in the godbus repository, which you may notice in the server code provided below. This is the server code:

package main

import (
    "fmt"
    "os"

    "github.com/godbus/dbus/v5"
    "github.com/godbus/dbus/v5/introspect"
)

const xml = `
<node>
    <interface name="org.freedesktop.notifications">
        <method name="notify">
            <arg direction="in" type="s"/>
            <arg direction="in" type="u"/>
            <arg direction="in" type="s"/>
            <arg direction="in" type="s"/>
            <arg direction="in" type="s"/>
            <arg direction="in" type="as"/>
            <arg direction="in" type="a{sv}"/>
            <arg direction="in" type="i"/>
            <arg direction="out" type="u"/>
        </method>

        <method name="getcapabilities">
            <arg direction="out" type="as"/>
        </method>

        <method name="getserverinformation">
            <arg direction="out" type="s"/>
            <arg direction="out" type="s"/>
            <arg direction="out" type="s"/>
            <arg direction="out" type="s"/>
        </method>

        <method name="closenotification">
            <arg direction="in" type="u"/>
        </method>

        <signal name="notificationclosed">
            <arg type="u" name="id"/>
            <arg type="u" name="reason"/>
        </signal>
    </interface>` + introspect.introspectdatastring + `</node> `

type notificationserver struct {
}

func (s *notificationserver) notify(appname string, replacesid uint32, appicon string, summary string, body string, actions []string, hints map[string]dbus.variant, expiretimeout int32) (uint32, *dbus.error) {
    fmt.printf("new notification: %s\n", body)
    return 0, nil
}

func (s *notificationserver) getcapabilities() ([]string, *dbus.error) {
    return []string{"action-icons", "actions", "body", "body-hyperlinks", "body-images", "body-markup", "icon-multi", "icon-static", "persistence", "sound"}, nil
}

func (s *notificationserver) getserverinformation() (string, string, string, string, *dbus.error) {
    return "antarctica", "antarctica.com", "1.0", "1.2", nil
}

func (s *notificationserver) closenotification(id uint32) *dbus.error {
    s.notificationclosed(id, 0)
    return nil
}
func (s *notificationserver) notificationclosed(id, reason uint32) {

}

func main() {
    conn, err := dbus.connectsessionbus()
    if err != nil {
        panic(err)
    }
    defer conn.close()

    reply, err := conn.requestname("com.antarctica.notification",
        dbus.nameflagdonotqueue)
    if err != nil {
        panic(err)
    }

    if reply != dbus.requestnamereplyprimaryowner {
        fmt.fprintln(os.stderr, "name already taken")
        os.exit(1)
    }
    server := notificationserver{}
    err = conn.export(server,"/org/freedesktop/notifications","org.freedesktop.notifications")
    if err != nil {
        panic(err)
    }
    conn.export(introspect.introspectable(xml), "/org/freedesktop/notifications", "org.freedesktop.dbus.introspectable")
    fmt.println("listening on com.antarctica.notification / /com/antarctica/notification ...")
    select {}
}

The problem now is that even if the client has access to the introspection xml:

$ gdbus introspect --session --dest com.antarctica.notification --object-path /org/freedesktop/notifications --xml

> returns xml

I cannot use the org.freedesktop.notifications method that I wrote in the server code. For example, notify is unknown/invalid, which is the same for each method:

$ dbus-send --session --print-reply=literal --dest=com.antarctica.notification /org/freedesktop/Notifications org.freedesktop.Notifications.Notify

> Error org.freedesktop.DBus.Error.UnknownMethod: Unknown / invalid method 'Notify'

Also in qdbusviewer when I try to execute any method it says "Unable to find method x at path /org/freedesktop/notifications in interface org.freedesktop.notifications"

What I tried:

  1. Check if dbus is running
  2. Check if my server is running
  3. I also tried restarting the dbus service and my computer
  4. I think the notificationserver instance (server) is not exported at all, but I don't know why

Correct answer


This works. You made two mistakes:

  1. com.antarctica.notification
  2. func (s *notificationserver)

You must request "org.freedesktop.notifications" as the name and cannot use pointers in functions.

  1. org.freedesktop.notifications
  2. func (notify server)
  3. (You don’t need to introspect either)
package main

import (
    "fmt"
    "os"

    "github.com/godbus/dbus/v5"
)

type notificationServer struct{}

func (s notificationServer) Notify(appName string, replacesID uint32, appIcon string, summary string, body string, actions []string, hints map[string]dbus.Variant, expireTimeout int32) (uint32, *dbus.Error) {
    fmt.Printf("New notification: %s\n", body)
    return 0, nil
}

func (s notificationServer) GetCapabilities() ([]string, *dbus.Error) {
    return []string{"action-icons", "actions", "body", "body-hyperlinks", "body-images", "body-markup", "icon-multi", "icon-static", "persistence", "sound"}, nil
}

func (s notificationServer) GetServerInformation() (string, string, string, string, *dbus.Error) {
    return "antarctica", "antarctica.com", "1.0", "1.2", nil
}

func main() {
    conn, err := dbus.ConnectSessionBus()
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    f := notificationServer{}
    conn.Export(f, "/org/freedesktop/Notifications", "org.freedesktop.Notifications")

    reply, err := conn.RequestName("org.freedesktop.Notifications", dbus.NameFlagDoNotQueue)
    if err != nil {
        panic(err)
    }
    if reply != dbus.RequestNameReplyPrimaryOwner {
        fmt.Fprintln(os.Stderr, "name already taken")
        os.Exit(1)
    }
    fmt.Println("Listening...")
    select {}
}

The above is the detailed content of Error org.freedesktop.DBus.Error.UnknownMethod: Unknown/invalid method 'Notify'. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete