0685: Pickup Protocol 2.0¶
- Authors: Sam Curren, James Ebert
- Status: ACCEPTED
- Since: 2024-05-01
- Status Note: Initial version
- Start Date: 2020-12-22
- Tags: feature, protocol
Summary¶
A protocol to facilitate an agent picking up messages held at a mediator.
Motivation¶
Messages can be picked up simply by sending a message to the Mediator with a return_route
decorator specified. This mechanism is implicit, and lacks some desired behavior made possible by more explicit messages.
This protocol is the explicit companion to the implicit method of picking up messages.
Tutorial¶
Roles¶
Mediator - The agent that has messages waiting for pickup by the Recipient.
Recipient - The agent who is picking up messages.
Flow¶
The status-request
message is sent by the Recipient to the Mediator to query how many messages are pending.
The status
message is the response to status-request
to communicate the state of the message queue.
The delivery-request
message is sent by the Recipient to request delivery of pending messages.
The message-received
message is sent by the Recipient to confirm receipt of delivered messages,
prompting the Mediator to clear messages from the queue.
The live-delivery-change
message is used to set the state of live_delivery
.
- When Live Mode is enabled, messages that arrive when an existing connection exists are delivered over the connection immediately, rather than being pushed to the queue. See Live Mode for more details.
Reference¶
Each message sent MUST use the ~transport
decorator as follows, which has been adopted from RFC 0092 transport return route protocol. This has been omitted from the examples for brevity.
Message Types¶
Status Request¶
Sent by the Recipient to the Mediator to request a status
message.
Example:¶
{
"@id": "123456781",
"@type": "https://didcomm.org/messagepickup/2.0/status-request",
"recipient_key": "<key for messages>"
}
recipient_key
is optional. When specified, the Mediator MUST only return status related to that recipient key. This allows the Recipient to discover if any messages are in the queue that were sent to a specific key. You can find more details about recipient_key
and how it's managed in 0211-route-coordination.
Status¶
Status details about waiting messages.
Example:¶
{
"@id": "123456781",
"@type": "https://didcomm.org/messagepickup/2.0/status",
"recipient_key": "<key for messages>",
"message_count": 7,
"longest_waited_seconds": 3600,
"newest_received_time": "2019-05-01 12:00:00Z",
"oldest_received_time": "2019-05-01 12:00:01Z",
"total_bytes": 8096,
"live_delivery": false
}
message_count
is the only REQUIRED attribute. The others MAY be present if offered by the Mediator.
longest_waited_seconds
is in seconds, and is the longest delay of any message in the queue.
total_bytes
represents the total size of all messages.
If a recipient_key
was specified in the status-request
message, the matching value MUST be specified
in the recipient_key
attribute of the status message.
live_delivery
state is also indicated in the status message.
Note: due to the potential for confusing what the actual state of the message queue is, a status message MUST NOT be put on the pending message queue and MUST only be sent when the Recipient is actively connected (HTTP request awaiting response, WebSocket, etc.).
Delivery Request¶
A request from the Recipient to the Mediator to have pending messages delivered.
Examples:¶
{
"@id": "123456781",
"@type": "https://didcomm.org/messagepickup/2.0/delivery-request",
"limit": 10,
"recipient_key": "<key for messages>"
}
limit
is a REQUIRED attribute, and after receipt of this message, the Mediator SHOULD deliver up to the limit
indicated.
recipient_key
is optional. When specified, the Mediator MUST only return messages sent to that recipient key.
If no messages are available to be sent, a status
message MUST be sent immediately.
Delivered messages MUST NOT be deleted until delivery is acknowledged by a messages-received
message.
Message Delivery¶
Messages delivered from the queue must be delivered in a batch delivery
message as attachments. The ID of each attachment is used to confirm receipt. The ID is an opaque value, and the Recipient should not infer anything from the value.
The ONLY valid type of attachment for this message is a DIDComm Message in encrypted form.
The recipient_key
attribute is only included when responding to a delivery-request
message that indicates a recipient_key
.
{
"@id": "123456781",
"~thread": {
"thid": "<message id of delivery-request message>"
},
"@type": "https://didcomm.org/messagepickup/2.0/delivery",
"recipient_key": "<key for messages>",
"~attach": [{
"@id": "<messageid>",
"data": {
"base64": ""
}
}]
}
This method of delivery does incur an encoding cost, but is much simpler to implement and a more robust interaction.
Messages Received¶
After receiving messages, the Recipient sends an ack message indiciating which messages are safe to clear from the queue.
Example:¶
{
"@type": "https://didcomm.org/messagepickup/2.0/messages-received",
"message_id_list": ["123","456"]
}
message_id_list
is a list of ids of each message received. The id of each message is present in the attachment descriptor of each attached message of a delivery
message.
Upon receipt of this message, the Mediator knows which messages have been received, and can remove them from the collection of queued messages with confidence. The mediator SHOULD send an updated status
message reflecting the changes to the queue.
Multiple Recipients¶
If a message arrives at a Mediator addressed to multiple Recipients, the message MUST be queued for each Recipient independently. If one of the addressed Recipients retrieves a message and indicates it has been received, that message MUST still be held and then removed by the other addressed Recipients.
Live Mode¶
Live mode is the practice of delivering newly arriving messages directly to a connected Recipient. It is disabled by default and only activated by the Recipient. Messages that arrive when Live Mode is off MUST be stored in the queue for retrieval as described above. If Live Mode is active, and the connection is broken, a new inbound connection starts with Live Mode disabled.
Messages already in the queue are not affected by Live Mode - they must still be requested with delivery-request
messages.
Live mode MUST only be enabled when a persistent transport is used, such as WebSockets.
Recipients have three modes of possible operation for message delivery with various abilities and level of development complexity:
- Never activate live mode. Poll for new messages with a
status_request
message, and retrieve them when available. - Retrieve all messages from queue, and then activate Live Mode. This simplifies message processing logic in the Recipient.
- Activate Live Mode immediately upon connecting to the Mediator. Retrieve messages from the queue as possible. When receiving a message delivered live, the queue may be queried for any waiting messages delivered to the same key for processing.
Live Mode Change¶
Live Mode is changed with a live-delivery-change
message.
Example:¶
Upon receiving the live_delivery_change
message, the Mediator MUST respond with a status
message.
If sent with live_delivery
set to true
on a connection incapable of live delivery, a problem_report
SHOULD be sent as follows:
{
"@type": "https://didcomm.org/notification/1.0/problem-report",
"~thread": {
"pthid": "<message id of offending live_delivery_change>"
},
"description": "Connection does not support Live Delivery"
}
Prior art¶
Version 1.0 of this protocol served as the main inspiration for this version. Version 1.0 suffered from not being very explicit, and an incomplete model of message delivery signaling.
Alternatives¶
- An alternative to deriving a message ID is to wrap each message in a delivery wrapper. This would enable the mediator to include a mediator managed id and metadata along with the message itself, but carries the downside of double encrypting messages and extra processing.
Implementations¶
The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation.
Name / Link | Implementation Notes |
---|---|