我们与EMS代码的连接最初设计不合理,并为我们收听的每个主题创建了一个TopicConnection对象。所以,实际上,每当我们订阅一个主题时,我们就会创建一个新的连接,一个新的会话,最后一个新的监听器。
我们想切换到单一连接模型。虽然通过共享一个连接对象并为每个主题创建一个新的会话对象,我可以在代码中轻松完成此操作,但我们不确定这是否会导致任何问题而无需代码。
我的理解是Tibco EMS客户端库在共享连接方面是线程安全的。实际上,连接只是一个管道,会话可以以线程安全的方式重新使用此管道。
这个假设是正确的还是还有更多呢?
答案 0 :(得分:7)
.NET EMS API基于JMS。在JMS中,Connection和Session对象被指定为线程安全的,可以在程序中重用。您完全正确,因为Connection对象只是表示EMS服务器的网络管道。 EMS用户指南声明:
连接是一个相当重量级的对象,因此大多数客户端将创建一次连接并保持打开直到客户端退出。如有必要,您的应用程序可以创建多个连接。
关于会议:
Session是用于生成或使用消息的单线程上下文。您可以使用Session对象创建Message Producers或Message Consumers。
基本上,除非您需要非常大的数量并且遇到性能限制,否则在应用程序中仅使用一个连接是完全安全的。会话控制在其中创建的任何生产者或消费者的事务/确认语义,但再次可以安全地重用。我可能会在应用程序中使用具有不同生命周期的模块的单独会话(在应用程序服务器中考虑单独的部署单元)。
您的EMS服务器安装将包含带有各种代码的示例目录(类似于 C:\ tibco \ ems \ 5.0 \ samples \ cs )。 csTopicSubscriber.cs 中的代码显示了如何编写单线程主题使用者。没有多线程主题消费者示例,但 csMsgConsumerPerf.cs 演示了如何使用队列。
请务必清理完成后创建的任何对象 - 例如完成后关闭主题使用者对象,会话和连接。与预取和容错重新连接设置结合使用时,泄漏句柄而不关闭它们会导致不可预测的行为。
答案 1 :(得分:0)
我认为只要共享属于同一个应用程序(exe,二进制)。 我们共享了相同的连接对象,并在代码中将其用作单例。
答案 2 :(得分:0)
同意先前的回答:不能在线程之间共享JMS会话,但是Connection可以/应该是。因此,每个应用程序的一个连接是可以的(确保您只启动/关闭它一次 - 最好在创建单个线程之前/之后)。
然后为每个线程创建并使用一个Session。请记住,当你关闭()一个Session时,它会阻塞,直到所有接收回调都真正返回。所以不要在回调的onMessage()中调用close()。