pub struct Connection { /* private fields */ }
Expand description
A D-Bus connection.
A connection to a D-Bus bus, or a direct peer.
Once created, the connection is authenticated and negotiated and messages can be sent or received, such as method calls or signals.
For higher-level message handling (typed functions, introspection, documentation reasons etc),
it is recommended to wrap the low-level D-Bus messages into Rust functions with the
proxy
and interface
macros instead of doing it directly on a Connection
.
Typically, a connection is made to the session bus with Connection::session
, or to the
system bus with Connection::system
. Then the connection is used with crate::Proxy
instances or the on-demand ObjectServer
instance that can be accessed through
Connection::object_server
.
Connection
implements Clone
and cloning it is a very cheap operation, as the underlying
data is not cloned. This makes it very convenient to share the connection between different
parts of your code. Connection
also implements std::marker::Sync
and std::marker::Send
so you can send and share a connection instance across threads as well.
Connection
keeps internal queues of incoming message. The default capacity of each of these is
64. The capacity of the main (unfiltered) queue is configurable through the set_max_queued
method. When the queue is full, no more messages can be received until room is created for more.
This is why it’s important to ensure that all crate::MessageStream
and
crate::blocking::MessageIterator
instances are continuously polled and iterated on,
respectively.
For sending messages you can use the Connection::send
method.
To gracefully close a connection while waiting for any outstanding method calls to complete,
use Connection::graceful_shutdown
. To immediately close a connection in a way that will
disrupt any outstanding method calls, use Connection::close
. If you do not need the
shutdown to be immediate and do not care about waiting for outstanding method calls, you can
also simply drop the Connection
instance, which will act similarly to spawning
graceful_shutdown
in the background.
§Examples
§Get the session bus ID
use zbus::Connection;
let connection = Connection::session().await?;
let reply_body = connection
.call_method(
Some("org.freedesktop.DBus"),
"/org/freedesktop/DBus",
Some("org.freedesktop.DBus"),
"GetId",
&(),
)
.await?
.body();
let id: &str = reply_body.deserialize()?;
println!("Unique ID of the bus: {}", id);
§Monitoring all messages
Let’s eavesdrop on the session bus 😈 using the Monitor interface:
use futures_util::stream::TryStreamExt;
use zbus::{Connection, MessageStream};
let connection = Connection::session().await?;
connection
.call_method(
Some("org.freedesktop.DBus"),
"/org/freedesktop/DBus",
Some("org.freedesktop.DBus.Monitoring"),
"BecomeMonitor",
&(&[] as &[&str], 0u32),
)
.await?;
let mut stream = MessageStream::from(connection);
while let Some(msg) = stream.try_next().await? {
println!("Got message: {}", msg);
}
This should print something like:
Got message: Signal NameAcquired from org.freedesktop.DBus
Got message: Signal NameLost from org.freedesktop.DBus
Got message: Method call GetConnectionUnixProcessID from :1.1324
Got message: Error org.freedesktop.DBus.Error.NameHasNoOwner:
Could not get PID of name ':1.1332': no such name from org.freedesktop.DBus
Got message: Method call AddMatch from :1.918
Got message: Method return from org.freedesktop.DBus
Implementations§
Source§impl Connection
impl Connection
Sourcepub async fn call_method<'d, 'p, 'i, 'm, D, P, I, M, B>(
&self,
destination: Option<D>,
path: P,
interface: Option<I>,
method_name: M,
body: &B,
) -> Result<Message>
pub async fn call_method<'d, 'p, 'i, 'm, D, P, I, M, B>( &self, destination: Option<D>, path: P, interface: Option<I>, method_name: M, body: &B, ) -> Result<Message>
Send a method call.
Create a method-call message, send it over the connection, then wait for the reply.
On successful reply, an Ok(Message)
is returned. On error, an Err
is returned. D-Bus
error replies are returned as Error::MethodError
.
Sourcepub async fn emit_signal<'d, 'p, 'i, 'm, D, P, I, M, B>(
&self,
destination: Option<D>,
path: P,
interface: I,
signal_name: M,
body: &B,
) -> Result<()>
pub async fn emit_signal<'d, 'p, 'i, 'm, D, P, I, M, B>( &self, destination: Option<D>, path: P, interface: I, signal_name: M, body: &B, ) -> Result<()>
Emit a signal.
Create a signal message, and send it over the connection.
Sourcepub async fn reply<B>(&self, call: &Header<'_>, body: &B) -> Result<()>where
B: Serialize + DynamicType,
pub async fn reply<B>(&self, call: &Header<'_>, body: &B) -> Result<()>where
B: Serialize + DynamicType,
Reply to a message.
Given an existing message (likely a method call), send a reply back to the caller with the
given body
.
Sourcepub async fn reply_error<'e, E, B>(
&self,
call: &Header<'_>,
error_name: E,
body: &B,
) -> Result<()>
pub async fn reply_error<'e, E, B>( &self, call: &Header<'_>, error_name: E, body: &B, ) -> Result<()>
Reply an error to a message.
Given an existing message (likely a method call), send an error reply back to the caller
with the given error_name
and body
.
Sourcepub async fn reply_dbus_error(
&self,
call: &Header<'_>,
err: impl DBusError,
) -> Result<()>
pub async fn reply_dbus_error( &self, call: &Header<'_>, err: impl DBusError, ) -> Result<()>
Reply an error to a message.
Given an existing message (likely a method call), send an error reply back to the caller using one of the standard interface reply types.
Sourcepub async fn request_name<'w, W>(&self, well_known_name: W) -> Result<()>
pub async fn request_name<'w, W>(&self, well_known_name: W) -> Result<()>
Register a well-known name for this connection.
When connecting to a bus, the name is requested from the bus. In case of p2p connection, the name (if requested) is used for self-identification.
You can request multiple names for the same connection. Use Connection::release_name
for
deregistering names registered through this method.
Note that exclusive ownership without queueing is requested (using
RequestNameFlags::ReplaceExisting
and RequestNameFlags::DoNotQueue
flags) since that
is the most typical case. If that is not what you want, you should use
Connection::request_name_with_flags
instead (but make sure then that name is requested
after you’ve set up your service implementation with the ObjectServer
).
§Caveats
The associated ObjectServer
will only handle method calls destined for the unique name of
this connection or any of the registered well-known names. If no well-known name is
registered, the method calls destined to all well-known names will be handled.
Since names registered through any other means than Connection
or Builder
API are not known to the connection, method calls destined to those names will only be
handled by the associated ObjectServer
if none of the names are registered through
Connection*
API. Simply put, either register all the names through Connection*
API or
none of them.
§Errors
Fails with zbus::Error::NameTaken
if the name is already owned by another peer.
Sourcepub async fn request_name_with_flags<'w, W>(
&self,
well_known_name: W,
flags: BitFlags<RequestNameFlags>,
) -> Result<RequestNameReply>
pub async fn request_name_with_flags<'w, W>( &self, well_known_name: W, flags: BitFlags<RequestNameFlags>, ) -> Result<RequestNameReply>
Register a well-known name for this connection.
This is the same as Connection::request_name
but allows to specify the flags to use when
requesting the name.
If the RequestNameFlags::DoNotQueue
flag is not specified and request ends up in the
queue, you can use fdo::NameAcquiredStream
to be notified when the name is acquired. A
queued name request can be cancelled using Connection::release_name
.
If the RequestNameFlags::AllowReplacement
flag is specified, the requested name can be
lost if another peer requests the same name. You can use fdo::NameLostStream
to be
notified when the name is lost
§Example
use zbus::{Connection, fdo::{DBusProxy, RequestNameFlags, RequestNameReply}};
use enumflags2::BitFlags;
use futures_util::stream::StreamExt;
let name = "org.freedesktop.zbus.QueuedNameTest";
let conn1 = Connection::session().await?;
// This should just work right away.
conn1.request_name(name).await?;
let conn2 = Connection::session().await?;
// A second request from the another connection will fail with `DoNotQueue` flag, which is
// implicit with `request_name` method.
assert!(conn2.request_name(name).await.is_err());
// Now let's try w/o `DoNotQueue` and we should be queued.
let reply = conn2
.request_name_with_flags(name, RequestNameFlags::AllowReplacement.into())
.await?;
assert_eq!(reply, RequestNameReply::InQueue);
// Another request should just give us the same response.
let reply = conn2
// The flags on subsequent requests will however be ignored.
.request_name_with_flags(name, BitFlags::empty())
.await?;
assert_eq!(reply, RequestNameReply::InQueue);
let mut acquired_stream = DBusProxy::new(&conn2)
.await?
.receive_name_acquired()
.await?;
assert!(conn1.release_name(name).await?);
// This would have waited forever if `conn1` hadn't just release the name.
let acquired = acquired_stream.next().await.unwrap();
assert_eq!(acquired.args().unwrap().name, name);
// conn2 made the mistake of being too nice and allowed name replacemnt, so conn1 should be
// able to take it back.
let mut lost_stream = DBusProxy::new(&conn2)
.await?
.receive_name_lost()
.await?;
conn1.request_name(name).await?;
let lost = lost_stream.next().await.unwrap();
assert_eq!(lost.args().unwrap().name, name);
§Caveats
- Same as that of
Connection::request_name
. - If you wish to track changes to name ownership after this call, make sure that the
fdo::NameAcquired
and/orfdo::NameLostStream
instance(s) are created before calling this method. Otherwise, you may loose the signal if it’s emitted after this call but just before the stream instance get created.
Sourcepub async fn release_name<'w, W>(&self, well_known_name: W) -> Result<bool>
pub async fn release_name<'w, W>(&self, well_known_name: W) -> Result<bool>
Deregister a previously registered well-known name for this service on the bus.
Use this method to deregister a well-known name, registered through
Connection::request_name
.
Unless an error is encountered, returns Ok(true)
if name was previously registered with
the bus through self
and it has now been successfully deregistered, Ok(false)
if name
was not previously registered or already deregistered.
Sourcepub fn is_bus(&self) -> bool
pub fn is_bus(&self) -> bool
Check if self
is a connection to a message bus.
This will return false
for p2p connections. When the p2p
feature is disabled, this will
always return true
.
Sourcepub fn unique_name(&self) -> Option<&OwnedUniqueName>
pub fn unique_name(&self) -> Option<&OwnedUniqueName>
The unique name of the connection, if set/applicable.
The unique name is assigned by the message bus or set manually using
Connection::set_unique_name
.
Sourcepub fn set_unique_name<U>(&self, unique_name: U) -> Result<()>
pub fn set_unique_name<U>(&self, unique_name: U) -> Result<()>
Set the unique name of the connection (if not already set).
This is mainly provided for bus implementations. All other users should not need to use this
method. Hence why this method is only available when the bus-impl
feature is enabled.
§Panics
This method panics if the unique name is already set. It will always panic if the connection is to a message bus as it’s the bus that assigns peers their unique names.
Sourcepub fn max_queued(&self) -> usize
pub fn max_queued(&self) -> usize
The capacity of the main (unfiltered) queue.
Sourcepub fn set_max_queued(&mut self, max: usize)
pub fn set_max_queued(&mut self, max: usize)
Set the capacity of the main (unfiltered) queue.
Sourcepub fn server_guid(&self) -> &OwnedGuid
pub fn server_guid(&self) -> &OwnedGuid
The server’s GUID.
Sourcepub fn executor(&self) -> &Executor<'static>
pub fn executor(&self) -> &Executor<'static>
The underlying executor.
When a connection is built with internal_executor set to false, zbus will not spawn a thread to run the executor. You’re responsible to continuously tick the executor. Failure to do so will result in hangs.
§Examples
Here is how one would typically run the zbus executor through tokio’s scheduler:
use zbus::connection::Builder;
use tokio::task::spawn;
#[tokio::main]
async fn main() {
let conn = Builder::session()
.unwrap()
.internal_executor(false)
.build()
.await
.unwrap();
{
let conn = conn.clone();
spawn(async move {
loop {
conn.executor().tick().await;
}
});
}
// All your other async code goes here.
}
Note: zbus 2.1 added support for tight integration with tokio. This means, if you use
zbus with tokio, you do not need to worry about this at all. All you need to do is enable
tokio
feature. You should also disable the (default) async-io
feature in your
Cargo.toml
to avoid unused dependencies. Also note that prior to zbus 3.0, disabling
async-io
was required to enable tight tokio
integration.
Sourcepub fn object_server(&self) -> &ObjectServer
pub fn object_server(&self) -> &ObjectServer
Get a reference to the associated ObjectServer
.
The ObjectServer
is created on-demand.
Note: Once the ObjectServer
is created, it will be replying to all method calls
received on self
. If you want to manually reply to method calls, do not use this
method (or any of the ObjectServer
related API).
Sourcepub fn monitor_activity(&self) -> EventListener
pub fn monitor_activity(&self) -> EventListener
Return a listener, notified on various connection activity.
This function is meant for the caller to implement idle or timeout on inactivity.
Sourcepub async fn peer_credentials(&self) -> Result<ConnectionCredentials>
pub async fn peer_credentials(&self) -> Result<ConnectionCredentials>
Return the peer credentials.
The fields are populated on the best effort basis. Some or all fields may not even make
sense for certain sockets or on certain platforms and hence will be set to None
.
§Caveats
Currently unix_group_ids
and linux_security_label
fields are not populated.
Sourcepub async fn close(self) -> Result<()>
pub async fn close(self) -> Result<()>
Close the connection.
After this call, all reading and writing operations will fail.
Sourcepub async fn graceful_shutdown(self)
pub async fn graceful_shutdown(self)
Gracefully close the connection, waiting for all other references to be dropped.
This will not disrupt any incoming or outgoing method calls, and will await their completion.
§Caveats
-
This will not prevent new incoming messages from keeping the connection alive (and indefinitely delaying this method’s completion).
-
The shutdown will not complete until the underlying connection is fully dropped, so beware of deadlocks if you are holding any other clones of this
Connection
.
§Example
let conn = Builder::session()?
.name("foo.bar.baz")?
.serve_at("/foo/bar/baz", MyInterface)?
.build()
.await?;
some_exit_condition.await;
conn.graceful_shutdown().await;
Trait Implementations§
Source§impl Clone for Connection
impl Clone for Connection
Source§fn clone(&self) -> Connection
fn clone(&self) -> Connection
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for Connection
impl Debug for Connection
Source§impl From<&Connection> for MessageStream
impl From<&Connection> for MessageStream
Source§fn from(conn: &Connection) -> Self
fn from(conn: &Connection) -> Self
Source§impl From<&MessageStream> for Connection
impl From<&MessageStream> for Connection
Source§fn from(stream: &MessageStream) -> Connection
fn from(stream: &MessageStream) -> Connection
Source§impl From<Connection> for Connection
impl From<Connection> for Connection
Source§fn from(conn: Connection) -> Self
fn from(conn: Connection) -> Self
Source§impl From<Connection> for Connection
impl From<Connection> for Connection
Source§fn from(conn: Connection) -> Self
fn from(conn: Connection) -> Self
Source§impl From<Connection> for MessageStream
impl From<Connection> for MessageStream
Source§fn from(conn: Connection) -> Self
fn from(conn: Connection) -> Self
Source§impl From<MessageStream> for Connection
impl From<MessageStream> for Connection
Source§fn from(stream: MessageStream) -> Connection
fn from(stream: MessageStream) -> Connection
Auto Trait Implementations§
impl Freeze for Connection
impl !RefUnwindSafe for Connection
impl Send for Connection
impl Sync for Connection
impl Unpin for Connection
impl !UnwindSafe for Connection
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)