根据 Java 消息服务规范的要求,当代理必须为客户端维护持久性状态时,连接必须提供一个唯一的客户端标识符。Message Queue 使用这些客户端标识符来跟踪主题目的地的长期订户。如果长期订户变为非活动状态,则代理会保留与该主题有关的所有传入消息,并在订户再次处于活动状态时传送这些消息。代理通过客户端标识符来标识订户。
客户端应用程序可以使用连接对象的 setClientID 方法以编程方式设置其自身的客户端标识符,这使得很难协调客户端标识符,从而不能确保每个标识符都是唯一的。通常,为客户端创建连接时,最好让 Message Queue 自动指定一个唯一的标识符。具体方法是,将连接工厂的 imqConfiguredClientID 属性设置为具有以下格式的值:
${u}factoryID
字符 ${u} 必须是该属性值的前四个字符。(如果大括号之间是 u 以外的任何字符,都会在创建连接时抛出异常;在任何其他位置,这些字符都没有特殊含义,将被视为纯文本。)factoryID 的值是唯一与此连接工厂对象关联的字符串。
为特定客户端创建连接时,Message Queue 通过将字符 ${u} 替换为 u:userName 来构建客户端标识符,其中 userName 是通过连接验证的用户名。这可以确保给定连接工厂创建的每个连接都有其自身的唯一客户端标识符,即使它们在其他所有方面都完全相同。例如,如果用户名为 Calvin,为连接工厂的 imqConfiguredClientID 属性指定的字符串为 ${u}Hobbes ,则指定的客户端标识符将为 u:CalvinHobbes。
如果两个客户端都尝试使用默认用户名 guest 获取连接,则此方案将不起作用,因为这两个客户端的客户端标识符具有相同的组成部分 ${u}。在这种情况下,只有请求连接的第一个客户端才能获取连接;第二个客户端的连接尝试将会失败,因为 Message Queue 不能创建两个具有相同客户端标识符的连接。
即使通过 imqConfiguredClientID 指定客户端标识符,客户端应用程序也可以使用连接方法 setClientID 来覆盖此设置。为了防止出现这种情况,可以将连接工厂的 imqDisableSetClientID 属性设置为 true。请注意,对于使用长期订户的应用程序,必须使用以下两种方法之一设置客户端标识符:使用 imqConfiguredClientID 以管理方式设置,或者使用 setClientID 以编程方式设置。