跳到主要内容

创建消息

消息在发布时由客户端应用程序显式创建,并且在匹配的消息投递过程中由消息 API 隐式创建。

Java RTO API

在本地库中创建一个对象,并为应用程序提供一个句柄。

C API

从堆存储中分配一个内存缓冲区,用于存储和发送/接收消息。

.NET API

创建一个 IMessage 对象以封装消息。

JavaScript 和 Node.js API

创建一个 solace.Message 对象以封装消息。

在创建消息时,需要考虑以下因素:

  • 消息所有权
  • 消息类型
  • 重置消息
  • 设置消息属性

消息所有权

在创建用于发布的消息时,有两种消息所有权模型:

会话无关(Session-independent)

在会话无关的消息所有权模型中,客户端应用程序可以在发送操作之间重复使用消息。消息按需分配,并且在客户端应用程序完成消息处理后显式释放。

会话相关(Session-dependent)

PubSub+ JCSMP API 还支持会话相关消息所有权模型。在此模型中,消息实例预先分配到一个生产者消息池中;客户端应用程序可以从消息池中“获取”一个消息实例,填充它并发送。发送操作返回后,API 会自动重置消息实例并将其“放回”消息池。此操作通过会话上的 Producer 接口完成。

会话相关消息不能用于批量发送(参见一次性发送多条消息)。

会话相关消息所有权模型主要用于与使用 PubSub+ JCSMP API 的现有应用程序保持向后兼容性。建议新的 Java 应用程序使用会话无关消息。如果在可能的情况下预先分配并重用消息,则使用会话无关消息所有权模型不会带来性能损失。

PubSub+ 消息 API使用方法
Java RTOSolclient.createMessageForHandle(...)
创建消息并将其绑定到给定的 MessageHandle
CsolClient_msg_alloc(...)
从堆存储中分配一个内存缓冲区,用于存储和发送/接收消息。
.NET- ContextFactory.CreateMessage()
  • ISession.CreateMessage()
    创建一个 IMessage 对象以封装消息。 | | JavaScript 和 Node.js | solace.SolclientFactory.createMessage()
    创建一个 solace.Message 对象以封装消息。 |

如何创建会话无关消息

相关示例

有关如何创建会话无关消息的示例,请参考 Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicPublisher 示例。

PubSub+ 消息 API使用方法
Java RTO不适用
C不适用
.NET不适用
JavaScript 和 Node.js不适用

如何创建会话相关消息

消息类型

消息 API 支持由消息负载定义的不同消息类型。

Java RTO API

Java RTO 提供了以下消息类型。

消息类描述
BytesMessage一个结构化的类,可用于发送包含二进制附件中未解释字节流的消息。

Java RTO 消息类

C、JavaScript、Node.js 和 .NET API

这些 API 定义了单一消息类型。在这些 API 中,消息负载可以通过消息辅助函数包含上述消息类型和类的任何组合。

重置消息

在会话无关消息所有权模型中重复使用消息时,可以释放与消息缓冲区关联的所有内存,使消息缓冲区重置为其初始状态(即,就像它刚刚被分配一样)。所有字段将被重置为其默认值。

Java RTO API 没有提供重置方法。如果使用 MessageHandle.destroy() 销毁消息,则必须再次调用 createMessageForHandle 为现在未绑定的句柄分配一个新消息。

PubSub+ 消息 API调用方法
Java RTO不适用
CsolClient_msg_reset()
.NETIMessage.reset()
JavaScript 和 Node.jssolace.Message.reset()

如何重置消息

设置消息属性

可以为保证消息设置许多重要的消息属性,这些属性会影响消息在发布时的路由方式。

有关可以设置的消息属性的完整列表,请参阅适用于相应消息 API 的 PubSub+ 消息 API 文档。

立即确认(ACK Immediately)

如果此属性设置为 false(默认值),事件代理应在达到发布窗口大小的三分之一或经过一秒钟时,为接收到的发布窗口中的消息发送确认。这些是事件代理上不可配置的阈值。

  • 此属性对传出的直接消息或客户端接收到的消息无效。
  • 此属性可能在消息传递给接收客户端之前被接收事件代理移除。因此,接收客户端不应依赖此属性存在。
PubSub+ 消息 API使用方法
Java RTOMessageHandle.setAckImmediately(...)
CsolClient_msg_setAckImmediately(...)
.NETIMessage.AckImmediately
JavaScript 和 Node.jssolace.Message.setAcknowledgementImmediately(...)

如何设置事件代理是否立即确认已发布消息

服务等级(Class-of-Service)

服务等级 2 是 Solace 的保留值;当前,服务等级为 2 的消息被视为低优先级。

必须使用每个 API 提供的数据结构设置 COS 值。不要直接使用整数设置值。

有关如何配置队列或主题端点以选择性地丢弃低优先级消息的信息,请参阅保证消息配置中的 reject-low-priority-msgreject-low-priority-msg-limit 队列 CONFIG 和主题端点 CONFIG 命令。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setUserCos(...)
CsolClient_msg_setClassOfService(...)
.NETIMessage.UserCos
JavaScript 和 Node.jssolace.Message.setUserCos(...)

如何设置 COS 标志

相关性ID(Correlation ID)

可以为消息设置一个唯一的相关性 ID(以字符串形式)。相关性 ID 可用于关联请求消息及其对应的回复。相关性 ID 也可以用作消息选择器中的标识符。

有关保证消息的请求/回复消息传递的信息,请参阅请求/回复消息传递。有关选择器的信息,请参阅使用选择器。

PubSub+ 消息 API调用方法
Java RTOMessageHandle.setCorrelationId(...)
CsolClient_msg_setCorrelationID(...)
.NETIMessage.CorrelationId
JavaScript 和 Node.jssolace.Message.setCorrelationId(...)

如何设置相关性 ID

死信队列资格(Dead Message Queue Eligibility)

已超过其 TTL 或最大重试次数的保证消息可以被移动到一个持久队列或主题端点的死信队列(DMQ),而不是被丢弃,如果这些消息被标记为 DMQ 合格。DMQ 只是一个被分配为另一个持久端点的 DMQ 的持久队列。有关更多信息,请参阅配置死信队列。

DMQ 资格是一个消息标志。值为 true 时,表示发布的消息符合 DMQ 资格。

为直接消息设置 DMQ 资格仅在消息的主题与端点的主题订阅匹配,并且事件代理将接收到的消息的传输模式更改为非持久化时才生效。有关如何修改接收到的消息的传输模式以匹配主题的信息,请参阅保证消息。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setDMQEligible(...)
CsolClient_msg_setDMQEligible(...)
.NETIMessage.DMQEligible
JavaScript 和 Node.jssolace.Message.setDMQEligible(...)

如何启用消息的 DMQ 资格

相关示例

有关如何使消息符合 DMQ 资格的示例,请参考适用于相应消息 API 的 messageTTLAndDeadMessageQueue 示例。

单一投递订阅者(Deliver-To-One Subscribers)

在发布时可以为保证消息设置单一投递属性。

单一投递标志仅影响直接传输模式的消息投递。因此,当为持久化或非持久化消息启用单一投递标志时,它不会影响消息投递行为,除非该消息的传输模式在匹配分配给队列或主题端点目标的主题订阅时被更改为直接。在这种情况下,传输模式被更改为直接的消息将仅投递给一个直接消息消费者,而不是所有消费者,即使可能有多个具有适当订阅的客户端能够接收该消息。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setDeliverToOne(...)
CsolClient_msg_setDeliverToOne(...)
.NET
IMessage.DeliverToOne
JavaScript 和 Node.jssolace.Message.setDeliverToOne(...)

如何设置单一投递消息标志

传输模式(Delivery Mode)

每条发布的消息都有一个传输模式。默认情况下,直接传输模式是默认值。要使用保证消息,通常需要将传输模式设置为持久化。

保证消息也支持非持久化传输模式;然而,此模式仅适用于 JMS 消息应用程序。

有关更多信息,请参阅消息传输模式。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setMessageDeliveryMode(...)
CsolClient_msg_setDeliveryMode(...)
.NETIMessage.DeliveryMode
JavaScript 和 Node.jssolace.Message.setDeliveryMode(...)

如何设置传输模式

相关示例

有关如何设置消息传输模式的示例,请参考 Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicPublisher 示例。

目标(Destination)

发布的保证消息根据其设置的队列或主题目标进行路由。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setDestination(...)
CsolClient_msg_setDestination(...)
.NETIMessage.Destination
JavaScript 和 Node.jssolace.Message.setDestination(...)

如何设置消息目标

相关示例

有关如何将消息发布到主题的示例,请参考 Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicPublisher 示例。

有关如何将消息发布到队列的示例,请参考 Java RTO、C 和 .NET API 的 QueueProvisionAndBrowse 示例,以及 JavaScript 和 Node.js API 的 QueueProducer 示例。

消息裁剪资格(Message Eliding Eligibility)

事件代理的消息裁剪功能允许客户端仅接收它们订阅的主题上发布的最新直接消息,且接收速率可管理。在需要较低消息速率或存在慢速消费者(即,消费消息速度不够快的客户端)的情况下,使用消息裁剪会非常有用。

要使用消息裁剪,需要满足以下条件:

  • 发布的消息必须标记为可裁剪。
  • 接收客户端应用程序必须通过其客户端用户名分配一个允许使用消息裁剪的客户端配置文件。客户端配置文件还设置了速率,以控制新可裁剪消息替换排队等待投递给客户端的先前版本的延迟间隔。有关如何配置客户端配置文件并将其分配给客户端的信息,请参阅配置客户端身份验证。

消息裁剪标志仅影响直接传输模式的消息投递。因此,当为持久化或非持久化消息启用消息裁剪标志时,它不会影响消息投递行为,除非该消息的传输模式在匹配客户端主题订阅时被更改为直接。在这种情况下,传输模式被更改为直接的消息可以被裁剪。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setElidingEligible(...)
CsolClient_msg_setElidingEligible(...)
.NETIMessage.ElidingEligible
JavaScript 和 Node.jssolace.Message.setElidingEligible(...)

如何启用消息裁剪资格

消息过期(Message Expiration)

可以为发送的消息设置一个过期时间(以毫秒为单位),从 1970 年 1 月 1 日午夜(UTC)开始计算。默认情况下,已发布消息的过期值为 0,表示消息永不过期。

只有当客户端显式设置大于 0 的过期值,并且 TTL 未设置或设置为 0 时,消息过期字段才会在事件代理中端到端传输。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setExpiration(...)
CsolClient_msg_setExpiration(...)
.NETIMessage.Expiration
JavaScript 和 Node.jssolace.Message.setGMExpiration(...)

如何设置消息过期时间

为了保持准确的消息过期值,同步连接到事件代理的客户端的系统时钟非常重要。

消息 TTL 是消息网络中防止过期消息投递给客户端的唯一机制。设置过期值对消息在网络中的生命周期没有影响。也就是说,即使消息的过期时间已过,它仍然会被投递给消费者。如果需要对过期消息采取进一步操作(例如丢弃收到的消息),则由接收应用程序负责执行该操作。

启用消息过期计算

要计算同时考虑消息 TTL 值的消息过期值,请为会话启用消息过期计算。默认情况下,为了提高系统性能,消息过期计算未启用。

启用消息过期计算后,如果消息的 TTL 值大于 0,API 会在消息发送或接收后更新消息的过期值,将其设置为消息 TTL 和 UTC 值的总和。

对于直接传输模式的消息,仅当事件代理自动将消息的传输模式从直接更改为非持久化时,设置 TTL 和过期值才会生效,因为消息的主题匹配分配给端点的主题订阅。有关如何更改消息的传输模式以匹配主题的信息,请参阅主题匹配与消息传输模式。

PubSub+ 消息 API会话属性
Java RTOSessionHandle.PROPERTIES.CALCULATE_MESSAGE_EXPIRATION
CSOLCLIENT_SESSION_PROP_CALCULATE_MESSAGE_EXPIRATION
.NETSessionProperties.CalculateMessageExpiration
JavaScript 和 Node.js不适用

如何启用消息过期计算

相关示例

有关如何设置过期时间或启用消息过期计算的示例,请参考适用于相应消息 API 的 messageTTLAndDeadMessageQueue 示例。

消息优先级(Message Priority)

可以为发布到事件代理的消息设置消息优先级值。当队列或主题端点被配置为尊重消息优先级时,事件代理使用此值按适当顺序投递消息。换句话说,高优先级的消息会在低优先级的消息之前发送。值 0 表示最低优先级,值 255 表示最高优先级(尽管事件代理将所有大于 9 的值视为优先级 9)。默认值为 4。

当端点被配置为强制执行消息优先级时,它增加了客户端在连接故障恢复后重复接收消息的机会。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setPriority(...)
CsolClient_msg_setPriority(...)
.NETIMessage.Priority
JavaScript 和 Node.jssolace.Message.setPriority(...)

如何设置消息优先级

分区键(Partition Key)

可以在消息中设置分区键,以利用分区队列。分区队列允许您轻松扩展事件网格中的消费者应用程序数量,同时保持具有相同分区键的所有已发布消息的消息顺序。PubSub+ 事件代理确保所有相关事件以正确的顺序投递给同一个消费者,并且在添加或移除消费者时重新平衡事件流。有关更多信息,请参阅分区队列。

通过在 API 中指定以下表中列出的用户消息属性来设置分区键。此值存储在消息的 JMSXGroupID 字段中,并在网络跳转之间保持不变。

以下表显示了如何在 PubSub+ 消息属性中配置键以使用分区队列。

PubSub+ 消息 API如何设置分区键
Java RTO使用 MessageHandle.setQueuePartitionKey() 方法设置 JMSXGroupID。此 API 仅使用 setter 和 getter 来配置和检索 JMSXGroupID。
如果需要,您也可以分别使用 MessageHandle.getQueuePartitionKey()MessageHandle.deleteQueuePartitionKey() 来检索或移除分区键。例如,以下将分区键设置为 Group-0
C使用 solClient_msg_createUserPropertyMap() 函数为消息创建用户属性映射。然后使用 solClient_container_addString(user_property_map, value, name) 函数在 CCSMP API 消息上设置名称-值对。
  • value — 表示分区键值的字符串。客户端应用程序在发布时设置该值。
  • name — 常量 SOLCLIENT_MESSAGE_USER_PROP_QUEUE_PARTITION_KEY 或字符串值 JMSXGroupID

以下示例将分区键值设置为 Group-0
| .NET | 使用 AddString(name,value) 在 .NET API 消息的用户属性映射上设置属性-值对。

  • name — 常量 MessageUserPropertyConstants_.SOLCLIENTUSER_PROP_QUEUE_PARTITION_KEY 或字符串值 JMSXGroupID
  • value — 表示分区键值的字符串。客户端应用程序在发布时设置该值。
    以下示例将分区键 value 设置为 Group-0

如何设置分区键

回复目标(ReplyTo Destinations)

当消息作为请求发布时,可以设置一个 ReplyTo 目标,以指示请求消息的回复应发送到何处。有关保证消息的请求/回复消息传递的信息,请参阅请求/回复消息传递。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setReplyTo(...)
CsolClient_msg_setReplyTo(...)
.NETIMessage.ReplyTo
JavaScript 和 Node.jssolace.Message.setReplyTo(...)

如何设置 ReplyTo 目标

相关示例

有关如何创建带有 ReplyTo 目标的保证请求消息的示例,请参考 Java RTO、C 和 .NET API 的 RRGuaranteedRequesterRRGuaranteedReplier 示例。对于 JavaScript 和 Node.js API,请参考 Basic RequestorBasicReplier 示例。

生存时间(Time-To-Live)

为了确保不会将旧消息投递给消费客户端,可以为每条要发布的保证消息设置生存时间(TTL,以毫秒为单位)。当队列或主题端点被配置为尊重消息 TTL 时,如果接收到的消息的 TTL 已过期,它可以被端点丢弃,或者如果消息符合死信队列(DMQ)资格,则可以移动到事件代理上配置的 DMQ。

默认情况下,已发布消息的 TTL 值为 0,表示消息永不过期。

有关如何配置端点以尊重消息 TTL 的信息,请参阅定义端点属性或 PubSub+ 消息 API 文档中使用的消息 API。有关使消息符合 DMQ 资格的信息,请参阅死信队列资格。

PubSub+ 消息 API使用方法
Java RTOMessageHandle.setTimeToLive(...)
CsolClient_msg_setTimeToLive(...)
.NETIMessage.TimeToLive
JavaScript 和 Node.jssolace.Message.setTimeToLive(...)

如何设置消息生存时间

相关示例

有关如何为已发布消息设置 TTL 的示例,请参考适用于相应消息 API 的 messageTTLAndDeadMessageQueue 示例。