通知在 Linux 上如何工作?

通知在 Linux 上如何工作?

我使用 ArchLinux,但这应该是无关紧要的,除了我经常提到的原因它的维基页面

我认为对通知如何工作以及“玩家”如何交互以使通知发挥作用并没有真正清楚的了解:

  • 有多少玩家参与其中?
  • 什么是通知服务器,它有什么作用服务
  • 什么是通知客户端,它有什么作用
  • notify-send我可以用这个东西来弹出通知吗?是(嗯,A) 客户?
  • 什么是通知守护进程
  • 以及有什么作用libnotify

为了理解这一点并在我的系统上设置通知,我提到了这个维基页面

我尝试过notification-daemon第一的。仅安装后这并不起作用。为了使调用notify-send成功,必须手动启动它(这意味着执行),以某种方式自动启动它,或者使用此内容/usr/lib/notification-daemon-1.0/notification-daemon创建一个文件/usr/share/dbus-1/services/org.freedesktop.Notifications.service

[D-BUS Service]
Name=org.freedesktop.Notifications
Exec=/usr/lib/notification-daemon-1.0/notification-daemon

然后我尝试了dunst,但是,一旦安装,就可以正常工作,从某种意义上说,就可以notify-send正常工作。我认为这从根本上来说是因为它在第一次调用时就启动了notify-send(这意味着我最初的印象是它在我卸载它之后也能工作;那是因为该dunst进程正在运行),但它是如何做到这一点的呢?

这两个,notification-daemon并且dunst都在该部分下通知服务器 > 独立,但它们也称为“通知守护进程”;这是否意味着通知守护进程通知服务器是同义词吗?如果不是,区别在哪里?

从用户(我)的角度来看,这两种美学之间有区别吗?我的意思是,当一个正在运行与另一个正在运行时,我发现通知看起来不同。顺便说一句,这里出现了“他们在提供什么服务?”的问题,因为在我看来,他们只是在等待其他工具向他们发送通知,以便他们可以以良好的方式展示它们。或者他们俩都做这两件事?无论哪种情况,通知最初来自哪里?他们如何到达通知框?

不管怎样,如果我想对通知进行自定义操作怎么办?假设我想获取所有这些内容并拥有自己的 shell 脚本,只需将它们附加到一个文件中~/notifications。这是否意味着我正在编写自己的通知服务器?还是客户?或者是什么?

我问的原因是我想尝试一下可以在xmobar状态栏(我与 XMonad 窗口管理器一起使用),所以我试图理解所有的部分。

我也看过statnot这看起来非常非常瘦,没有多余的装饰,但是参考我的上一段,感觉 usingstatnot仍然意味着我仍然需要编写一个配置,通过 functionupdate_text调用 xmobar 或 xmonad 公开的一些 API。这样我就无法控制,比如说,我想一次显示多少个通知。

我有点迷失了:/

试图从以下方面理解我的这个问题的含义:桌面通知规范没有成功:D


(1)但是我的 中存在一个预先存在的“错误” ~/.xinitrc,所以我必须首先解决它

答案1

什么是通知服务器,它有什么作用?

在一般术语中,服务器是客户端以某种方式连接到的程序(无论是通过网络还是通过本地 IPC 机制)。因此,通知服务器是一个接受来自客户端的“显示通知”请求并代表它们显示通知的程序。

什么是通知客户端,它有什么作用?

任何程序用途通知服务器成为“通知客户端”。这又不是特定于通知的术语;这是关于总体架构的。

我可以用这个通知发送来弹出通知吗?是(嗯,一个)客户吗?

是的,在本例中是客户。其目的主要是为了可以让通知弹出;应用程序不运行它,因为它们可以直接在自己的进程中执行相同的操作。

什么是通知守护进程?

与通知服务器完全相同。

术语“守护进程”有一些不同的含义。它指的是任何一种背景服务,无论它是否是“服务器” - 但在这种情况下,负责显示实际通知弹出窗口的程序同时是服务器和守护程序(因为它像守护程序一样在后台运行,并接受像服务一样请求)。

而libnotify的作用是什么?

它是一个小型库,可供通知客户端使用,以抽象出正在使用的 IPC 机制的细节(以及协议版本之间的差异)。该程序不需要了解 D-Bus 和接口,只需了解即可notify_notification_new(...)

(也就是说,许多应用程序选择直接实现通信,例如使用 libdbus 进行必要的调用 - 这是一个非常简单的协议,因此这两个选项可能同样常见。)

客户端(如 libnotify)和通知服务器之间使用的协议也经常被误称为“libnotify 协议”。

从用户(我)的角度来看,这两种美学之间有区别吗?我的意思是,当一个正在运行与另一个正在运行时,我发现通知看起来不同

那是字面上地区别。这个想法是每个桌面环境(GNOME、KDE ​​等)都有自己的通知服务器,该服务器将显示针对该桌面环境定制的弹出窗口 - 外观、设置、行为等。

(它甚至不一定是一个单独的守护进程;例如,在 GNOME 和 AwesomeWM 中,通知服务由桌面 shell 本身提供。)

顺便说一句,这里出现了“他们在提供什么服务?”的问题,因为在我看来,他们只是在等待其他工具向他们发送通知,以便他们可以以良好的方式展示它们。

是的,但是“等待其他工具向他们发送通知”才算“提供”某些东西。服务不一定要返回一些数据——任何系统中都有大量服务或多或少是单向的,即它们的工作是某事而不是返回某物。

不管怎样,如果我想对通知进行自定义操作怎么办?假设我想获取所有这些内容并拥有自己的 shell 脚本,只需将它们附加到文件 ~/notifications 中即可。这是否意味着我正在编写自己的通知服务器?还是客户?或者是什么?

如果它实现了通知协议,即客户端与之通信的商定方法,那么您将编写自己的“通知服务器”。对于大多数 Linux 系统来说,事实上的标准是通过 D-Bus 实现“org.freedesktop.Notifications”接口——如果你实现了它,你就拥有了一个通知服务器。

(虽然通过 shell 脚本来做到这一点确实很困难,但考虑到该接口由大约两个函数组成,大约 10 行 Python 或 Perl 就可以完成。)

我首先尝试过通知守护进程。仅安装后这不起作用。为了成功调用 notification-send,必须手动启动它(这意味着执行 /usr/lib/notification-daemon-1.0/notification-daemon),以某种方式自动启动它,或者在 /usr/ 创建一个文件share/dbus-1/services/org.freedesktop.Notifications.service 包含此内容

[D-BUS Service]
Name=org.freedesktop.Notifications
Exec=/usr/lib/notification-daemon-1.0/notification-daemon

故意不存在此文件,因为这意味着只有一个程序提供此特定服务 - 而实际上,一个程序可能安装了多个桌面环境,每个桌面环境都有自己的通知服务,并且 D-Bus 没有机制来区分一个程序的优先级实施或其他。

因此,虽然许多其他 D-Bus 服务是可自动启动的,但大多数通知服务器故意不是自动启动的,这样它们就不会被选择在“错误”的桌面环境中启动。桌面环境旨在“手动”启动适当的服务,例如,~/.xinitrc如果您这样做,则可以从您的服务启动它。

然后我尝试了 Dunst,但是一旦安装,它就可以工作,从某种意义上说,通知发送就可以工作。我认为这从根本上来说是因为它在第一次调用notify-send时就启动了(这意味着我最初的印象是它在我卸载它之后也能工作;那是因为dunst进程正在运行),但是它是如何做的那?

它使用与上面描述的完全相同的方法 - 它的包实际上包含一个 D-Bus .service 文件:

$ cat /usr/share/dbus-1/services/org.knopwob.dunst.service
[D-BUS服务] 名称=org.freedesktop.Notifications 执行=/usr/bin/dunst SystemdService=dunst.service

唯一的区别是实际文件不是以其应该提供的服务命名的(dbus-daemon 不会对“用户”服务强制执行此要求)。

我还查看了 statnot ,它看起来非常非常瘦,没有多余的装饰,但是参考我的上一段,感觉使用 statnot 仍然意味着我仍然需要通过函数 update_text 编写一个配置,调用 xmobar 或 xmonad 公开的一些 API。这样我就无法控制,比如说,我想一次显示多少个通知。

这似乎是不可避免的。如果您想要自定义逻辑,那么您需要编写自定义逻辑。

例如,我曾经编写过一个通知守护进程使用 dzen2作为“弹出窗口”。您可以在 Notify() 方法中实现您喜欢的任何逻辑。

答案2

我认为对通知如何工作以及“玩家”如何交互以使通知发挥作用并没有真正清楚的了解:

从技术上讲(与实现无关),您至少需要一个处理通知(例如接收和处理它们)的守护进程,一种其他进程将通知移交给所述守护进程的方法,以及关于通知内容的协议(例如标准)从应用程序传递到守护程序的数据看起来像是可以进行处理的。

要填补大多数 Linux 桌面环境的空白:

  • 有一个通知守护进程(许多桌面环境(例如 Gnome)带来了自己的实现,这些实现是通过用户会话启动的;在其他情况下,如果您使用更小的桌面,则可能必须为此设置一个通知守护进程服务;有不同的后者的实现可用,mako 为 Wayland 桌面命名了一个)。
  • 通知守护程序(如果它符合桌面通知规范)公开 D-BUS 接口(D-BUS 是允许进程之间通信的消息传递系统),然后其他进程使用该接口向守护程序发送通知。
  • 桌面通知规范定义了守护程序期望作为有效通知传递的内容以及通知可以具有哪些参数(我建议阅读规范以更深入地了解这一点:桌面通知规范

而libnotify的作用是什么?

简而言之,Libnotify 是一个库,提供将符合桌面通知规范的通知发送到也符合此标准的通知守护程序的功能。如果您正在构建一个应支持 Linux 上的桌面通知的应用程序,您可以使用 libnotify 来实现这一点。

相关内容