ObjectDisposedException thrown when creating the Session

Jul 25, 2014 at 10:29 PM
I'm getting "ObjectDisposedException" exception after connect and trying to create the session:

conn = new Connection(address);
var amqpSession = new Session(conn);

After invoke of 'new Session(conn)' the exception is thrown here:

public static ProtocolHeader ReadHeader(ITransport transport)
    {
        byte[] smallBuffer = new byte[8];
        if (!ReadBuffer(transport, smallBuffer, 0, 8))
        {
            throw new ObjectDisposedException(transport.GetType().Name);
        }
. . .

How can I find out the reason for this failure?

Here is a trace:

SEND AMQP 3 1 0 0
SEND sasl-init(mechanism:PLAIN,initial-response:********,hostname:obfuscated.servicebus.windows.net)
RECV AMQP 3 1 0 0
RECV sasl-mechanisms(sasl-server-mechanisms:System.Object[])
RECV sasl-outcome(code:0,additional-data:57656C636F6D6521)
SEND AMQP 0 1.0.0
#### Exception System.ObjectDisposedException - 0x00000000 (7) ####
#### Message: SaslTransport
#### Amqp.Framing.Reader::ReadHeader [IP: 001c] ####
#### Amqp.Connection+Pump::PumpThread [IP: 000c] ####
A first chance exception of type 'System.ObjectDisposedException' occurred in Amqp.NetMF.dll
Additional information: SaslTransport
Editor
Jul 26, 2014 at 11:53 AM
I see that you are using .Net Micro Framework version (Amqp.NetMF.dll assembly).
Are you using the emulator ?

If yes, it doesn't work due to a bug in the emulator network libraries as described here :

http://code.msdn.microsoft.com/OBD-Recorder-for-Net-Micro-b927ce94

Paolo
Editor
Jul 26, 2014 at 12:01 PM
I also see that you are using an old version of the library ...

RECV sasl-mechanisms(sasl-server-mechanisms:System.Object[])

The new trace solves the bug on showing object collection values instead of System.Object[].

However, if you want to "play" with .Net Micro Framework version you have following ways :
  • no emulator due to a bug in the network libraries
  • Netduino Plus boards but not with Service Bus because it needs SSL/TLS (for AMQPS) and Netduino Plus firmware doesn't support SSL/TLS. Netduino Plus boards can work with local broker without SSL/TLS (only AMQP) like Apache ActiveMQ or Qpid Proton Broker. Same for FEZ Hydra boards from GHI (no SSL/TLS support)
  • for full support with Service Bus you have to use FEZ Spider or FEZ Raptor boards that support SSL/TLS and so AMQPS
Paolo.
Jul 27, 2014 at 2:59 PM
Hi Paolo,

thanks for yo9ur summary.
I alre3ady starved on trying of all steps in your list :)
That's the reason why I do not use emulator with SSL and no netduino device :)
I use the FEZ Spider with Ethernet module.

Assuming that the problem is in the library version, it would mean that my version does not work at all. It fails by trying to establish the session.
So I tried with my HTTPS (no amqp) implementation to be sure that SSL support is not the cause of the failure.
The HTTPS version works fine.

RECAP:
  1. I'm not able to establish the session with AMQP Lite.
  2. Sending of messages to SB with HTTPS works fine.
  3. Using FEZ Spider device (no emulator)
Btw.: How is the version tracked in the amqplite source code? Assembly version is 1.0 and CodePlex track it as 0.1.
Editor
Jul 27, 2014 at 3:40 PM
Ok...it's better to have more information so all my questions ;-)
I haven't a FEZ Spider board to try on.

Regarding AMQP version library, are you using the source downloaded from "Downloads" tab ?
It's the first commit on May 12.

The best thing is to use last version related to the last commit on July 24 from "Source Code" tab.
Try to use it and update me with a feedback.

Paolo.
Coordinator
Jul 28, 2014 at 12:21 AM
Yes, try the latest code and let us know if you still see the exception. I guess this might be caused by issue #12. The SSL connection should be fine since you have received the SASL protocol header and some frames already.

For version tracking, the assembly version should also be 0.1. I will update it soon.

Thanks.

Xin
Jul 29, 2014 at 7:47 PM
Just downloaded the version from 27th July from here:
https://amqpnetlite.codeplex.com/releases/view/122138

Unfortunately I'm getting the same error. :(

SEND AMQP 3 1 0 0
SEND sasl-init(mechanism:PLAIN,initial-response:,hostname:.servicebus.windows.net)
RECV AMQP 3 1 0 0
RECV sasl-mechanisms(sasl-server-mechanisms:[PLAIN,EXTERNAL])
RECV sasl-outcome(code:0,additional-data:57656C636F6D6521)
SEND AMQP 0 1.0.0
SEND (ch=0) open(container-id:4ffcfa3f-3fd6-53aa-957e-375263582e57,host-name:frankfurt.servicebus.windows.net,max-frame-size:16384,channel-max:3)
#### Exception System.ObjectDisposedException - 0x00000000 (7) ####
#### Message: SaslTransport
#### Amqp.Framing.Reader::ReadHeader [IP: 001c] ####
#### Amqp.Connection+Pump::PumpThread [IP: 000c] ####
A first chance exception of type 'System.ObjectDisposedException' occurred in Amqp.NetMF.dll
Additional information: SaslTransport
Editor
Jul 30, 2014 at 7:41 AM
As I said I can't try it because I don't have a FEZ Spider....
However,
can you check if exception is thrown inside ReadHeader() method in Reader class on the following line...
byte[] smallBuffer = new byte[8];
            if (!ReadBuffer(transport, smallBuffer, 0, 8))
            {
                throw new ObjectDisposedException(transport.GetType().Name);
            }
You can set a breakpoint on the exception thrown.

Paolo.
Jul 30, 2014 at 7:54 AM
It is thrown, because ReadBuffer() method didn't read any data.
Is there somewhere some timeout values which I could increase?
Editor
Jul 30, 2014 at 8:10 AM
Ok ... my guess was right ... now

In the TcpTransport class (under NetMF folder), an SslSocket object is instantiated when ConnectAsync() is called.
Set a breakpoing at the end of ConnectAsync() method and check how much is the default read timeout of SslSocket object (that derives from SslStream).
In .Net MF it seems not to be infinite/blocking.

Can you give me this information please ?

Paolo.
Editor
Jul 30, 2014 at 8:14 AM
If timeout isn't infinite...you can change ConnectAsync() in following way :
if (sslHost != null)
            {
                SslSocket sslSocket = new SslSocket(socket);
                sslSocket.ReadTimeout = -1;
                sslSocket.AuthenticateAsClient(
                    sslHost,
                    null,
                    noVerification ? SslVerification.NoVerification : SslVerification.VerifyPeer,
                    SslProtocols.Default);
                this.socketTransport = sslSocket;
            }
I Added following line :

sslSocket.ReadTimeout = -1;

for infinite timeout before start SSL authentication.

Paolo.
Jul 30, 2014 at 8:51 PM
Unfortunately this didn't help :(

The receive call does not timeout. Instead Receive() does not return any byte and exit with count == 0 (true)
It seems to be some handshaking issue?!

static bool ReadBuffer(ITransport transport, byte[] buffer, int offset, int count)
    {
        while (count > 0)
        {
            int bytes = transport.Receive(buffer, offset, count);
            offset += bytes;
            count -= bytes;
            if (bytes == 0)
            {
                break;
            }
        }

        return count == 0;
    }