2012-11-27 30 views
0

我有聽的ActiveMQ的跺腳服務器上的目標(隊列或主題,也沒關係),並簡單地以下控制檯程序記錄它接收到控制檯消息:爲什麼我的流正在被同伴關閉?

using System; 
using Apache.NMS.Stomp; 
using Apache.NMS; 
using Apache.NMS.Util; 

namespace StompTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       var connectionFactory = new ConnectionFactory("stomp:tcp://mybroker:61613"); 

       var connection = connectionFactory.CreateConnection(); 
       connection.ExceptionListener += new ExceptionListener(connection_ExceptionListener); 
       connection.Start(); 

       var session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); 

       IDestination dest = SessionUtil.GetDestination(session, "queue://MyQueue"); 

       var consumer = session.CreateConsumer(dest); 
       consumer.Listener += new MessageListener(consumer_Listener); 

       Console.ReadKey(); 
      } 
      catch (NMSException ex) 
      { 
       Console.WriteLine("NMSException !! ==> " + ex.Message); 
      } 
     } 

     static void connection_ExceptionListener(Exception exception) 
     { 
      Console.WriteLine("Exception!! ==> " + exception.ToString()); 
     } 

     static void consumer_Listener(IMessage message) 
     { 
      var textMessage = message as ITextMessage; 
      if (textMessage == null) 
       Console.WriteLine("No ITextMessage..."); 
      else 
       Console.WriteLine("Received => " + textMessage.Text); 
     } 
    } 
} 

當我啓動它時,只要我不斷髮送消息,它就可以正常工作。但是,如果有30秒不活動,我會得到一個例外。出現這種情況,即使沒有將消息發送到隊列:

Exception!! ==> Apache.NMS.Stomp.IOException: Peer closed the stream. 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadLine(BinaryReader dataIn) in c:\d 
ev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 284 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadCommandHeader(BinaryReader dataIn 
) in c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 208 
    at Apache.NMS.Stomp.Protocol.StompFrame.FromStream(BinaryReader dataIn) in c: 
\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 197 
    at Apache.NMS.Stomp.Protocol.StompWireFormat.Unmarshal(BinaryReader dataIn) i 
n c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompWireFormat.cs:line 121 
    at Apache.NMS.Stomp.Transport.Tcp.TcpTransport.ReadLoop() in c:\dev\NMS.Stomp 
\src\main\csharp\Transport\Tcp\TcpTransport.cs:line 279 

從谷歌上搜索周圍,並讀取Apache.NMS源代碼,我想通了,它不得不做的事'InactivityMonitor',顯然,當我在連接字符串上指定參數transport.useInactivityMonitor=false,我沒有得到異常,並且一切正常。

但是據我所知我瞭解的一切,這inactivityMonitor有一個目的:確保「死」連接檢測到並妥善清理。

所以一定有其他的錯誤!我添加了一個簡單的控制檯示蹤劑上面的代碼,並沒有transport.useInactivityMonitor=false參數連接時是這樣的輸出:

Info: Connecting to: tcp://mybroker:61613/ 
Debug: Opening socket to: mybroker on port: 61613 
Debug: Connected to mybroker:61613 using InterNetwork protocol. 
Debug: Creating Inactivity Monitor: 1 
Debug: StompWireFormat - Marshaling: ConnectionInfo[ConnectionId=ID:mypc-309 
6-634896376801461632-0:0, Host=mybroker, MaxInactivityDuration=30000, ReadChec 
kInterval=30000, WriteCheckInterval=10000, MaxInactivityDurationInitialDelay=0, 
ClientId=ID:mypc-3096-634896376801461632-1:0, Password=, UserName=] 
Debug: StompWireFormat - Writing StompFrame[ Command=CONNECT, Properties={ heart 
-beat=10000,30000 client-id=ID:mypc-3096-634896376801461632-1:0 accept-versi 
on=1.0,1.1 host=mybroker}, Content=] 
Debug: StompWireFormat - Received StompFrame[ Command=CONNECTED, Properties={ ve 
rsion=1.1 server=ActiveMQ/5.6.0 session=ID:mypc-3096-634896376801461632-1:0 
heart-beat=0,0}, Content=System.Byte[]] 
Debug: InactivityMonitor[1]: Read Check time interval: 30000 
Debug: InactivityMonitor[1]: Initial Delay time interval: 10000 
Debug: InactivityMonitor[1]: Write Check time interval: 10000 
Debug: InactivityMonitor[1]: Starting the Monitor Timer. 
Debug: StompWireFormat - Received StompFrame[ Command=KEEPALIVE, Properties={}, 
Content=] 
Debug: InactivityMonitor[1]: New Keep Alive Received at -> 18:28:00.419 
Debug: StompWireFormat - Marshaling: ConsumerInfo[ConsumerId=ID:mypc-3096-63 
4896376801461632-0:0:1:1, Destination=queue://MyQueue, Ack Mode=AutoAcknowledge, 
PrefetchSize=1000, MaximumPendingMessageLimit=0, DispatchAsync=True, Selector=, 
SubscriptionName=, NoLocal=False, Exclusive=False, Retroactive=False, Priority= 
0, Transformation] 
Debug: StompWireFormat - Writing StompFrame[ Command=SUBSCRIBE, Properties={ id= 
ID:mypc-3096-634896376801461632-0:0:1:1 receipt=2 activemq.dispatchAsync=Tru 
e activemq.maximumPendingMessageLimit=0 activemq.priority=0 ack=client activemq. 
prefetchSize=1000 transformation=jms-xml destination=/queue/MyQueue}, Content=] 
Debug: StompWireFormat - Received StompFrame[ Command=RECEIPT, Properties={ rece 
ipt-id=2}, Content=System.Byte[]] 
Debug: StompWireFormat - Received StompFrame[ Command=KEEPALIVE, Properties={}, 
Content=] 
Debug: InactivityMonitor[1]: New Keep Alive Received at -> 18:28:00.508 
Debug: CheckConnection: Timer Elapsed at 27/11/2012 18:28:10 
Debug: InactivityMonitor[1]: Message sent since last write check. Resetting flag 
. 
Debug: InactivityMonitor[1]: A receive is in progress or already failed. 
Debug: CheckConnection: Timer Elapsed at 27/11/2012 18:28:20 
Debug: InactivityMonitor[1]: No Message sent since last write check. Sending a K 
eepAliveInfo. 
Debug: InactivityMonitor[1]: A read check is not currently allowed. 
Debug: InactivityMonitor[1] perparing for another Write Check 
Debug: InactivityMonitor[1] Write Check required sending KeepAlive. 
Debug: StompWireFormat - Marshaling: KeepAliveInfo[ commandId = 0, responseRequi 
red = False, ] 
Debug: StompWireFormat - Writing StompFrame[ Command=KEEPALIVE, Properties={}, C 
ontent=] 
Debug: CheckConnection: Timer Elapsed at 27/11/2012 18:28:30 
Debug: InactivityMonitor[1]: No Message sent since last write check. Sending a K 
eepAliveInfo. 
Debug: InactivityMonitor[1]: A read check is not currently allowed. 
Debug: InactivityMonitor[1] perparing for another Write Check 
Debug: InactivityMonitor[1] Write Check required sending KeepAlive. 
Debug: StompWireFormat - Marshaling: KeepAliveInfo[ commandId = 0, responseRequi 
red = False, ] 
Debug: StompWireFormat - Writing StompFrame[ Command=KEEPALIVE, Properties={}, C 
ontent=] 
Debug: Exception received in the Inactivity Monitor: Apache.NMS.Stomp.IOExceptio 
n: Peer closed the stream. 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadLine(BinaryReader dataIn) in c:\d 
ev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 284 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadCommandHeader(BinaryReader dataIn 
) in c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 208 
    at Apache.NMS.Stomp.Protocol.StompFrame.FromStream(BinaryReader dataIn) in c: 
\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 197 
    at Apache.NMS.Stomp.Protocol.StompWireFormat.Unmarshal(BinaryReader dataIn) i 
n c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompWireFormat.cs:line 121 
    at Apache.NMS.Stomp.Transport.Tcp.TcpTransport.ReadLoop() in c:\dev\NMS.Stomp 
\src\main\csharp\Transport\Tcp\TcpTransport.cs:line 279 
Exception!! ==> Apache.NMS.Stomp.IOException: Peer closed the stream. 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadLine(BinaryReader dataIn) in c:\d 
ev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 284 
    at Apache.NMS.Stomp.Protocol.StompFrame.ReadCommandHeader(BinaryReader dataIn 
) in c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 208 
    at Apache.NMS.Stomp.Protocol.StompFrame.FromStream(BinaryReader dataIn) in c: 
\dev\NMS.Stomp\src\main\csharp\Protocol\StompFrame.cs:line 197 
    at Apache.NMS.Stomp.Protocol.StompWireFormat.Unmarshal(BinaryReader dataIn) i 
n c:\dev\NMS.Stomp\src\main\csharp\Protocol\StompWireFormat.cs:line 121 
    at Apache.NMS.Stomp.Transport.Tcp.TcpTransport.ReadLoop() in c:\dev\NMS.Stomp 
\src\main\csharp\Transport\Tcp\TcpTransport.cs:line 279 
Debug: TransportFilter disposing of next Transport: MutexTransport 
Debug: TransportFilter disposing of next Transport: InactivityMonitor 
Debug: TransportFilter disposing of next Transport: TcpTransport 
Info: Closing The Session with Id ID:mypc-3096-634896376801461632-0:0:1 
Debug: Closing down the Consumer 
Error: Error during session close: Apache.NMS.Stomp.IOException: Channel was ina 
ctive for too long: tcp://mybroker:61613/ 
    at Apache.NMS.Stomp.Connection.Oneway(Command command) in c:\dev\NMS.Stomp\sr 
c\main\csharp\Connection.cs:line 539 
    at Apache.NMS.Stomp.MessageConsumer.DoClose() in c:\dev\NMS.Stomp\src\main\cs 
harp\MessageConsumer.cs:line 252 
    at Apache.NMS.Stomp.Session.DoClose() in c:\dev\NMS.Stomp\src\main\csharp\Ses 
sion.cs:line 307 
Info: Closed The Session with Id ID:mypc-3096-634896376801461632-0:0:1 

所以我覺得我的客戶被「踢」由經紀人,對於處於非活動狀態的時間太長。但我不明白爲什麼,從上面的日誌來看,我的客戶實際上是在發送「keepalive」消息,因爲它應該如此。所以它不應該無效。

我沒有選擇如何繼續解決這個問題。如果有人對此有所瞭解,大多會感激!

更新
版本號:

  • 庫:Apache.NMS.Stomp V1.5.3
  • 經紀人:阿帕奇的ActiveMQ 5.6.0
+0

應該添加庫和代理版本的詳細信息。 –

+0

@TimBish:我添加了所需的信息。 – fretje

+0

@fretje:你找到了解決辦法嗎?我也遇到了這個問題,連接不能從中恢復。 – PeterBelm

回答

3

嘗試使用跺腳故障轉移運輸。因此,而不是...

var connectionFactory = new ConnectionFactory("stomp:tcp://mybroker:61613"); 

使用...

var connectionFactory = new ConnectionFactory("failover:tcp://mybroker:61613"); 

現在,而不是這個ExceptionListener事件被提出,它是由你來理清,傳輸將自動重新連接。

提示:如果需要在斷開/重新連接發生時通知您,則會引發Connection對象上的ConnectionInterruptedListener和ConnectionResumedListener事件。

另外:

我推薦使用Session.CreateDurableConsumer而不僅僅是Session.CreateConsumer。這樣您就不會在斷開/重新連接期間丟失任何消息。

希望這可以幫助別人。

相關問題