0

ActiveMQ Stompサーバーで宛先(キューまたはトピック、関係ありません)をリッスンし、受信したメッセージをコンソールに記録する次のコンソールプログラムがあります。

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

ですから、私のクライアントは、あまりにも長い間非アクティブであったために、ブローカーによって「キック」されていると思います。しかし、上記のログから、クライアントが実際に「キープアライブ」メッセージを送信している理由がよくわかりません。したがって、非アクティブであってはなりません。

この問題をどのように進めるかについては、選択肢がありません。誰かがこれについて何らかの洞察を持っているなら、それは大抵感謝されるでしょう!

更新
バージョン番号:

  • ライブラリ:Apache.NMS.Stomp v1.5.3
  • ブローカー:Apache ActiveMQ 5.6.0
4

1 に答える 1