Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alchemy-Websockets - WebSocketClient throws a NullReferenceException

Tags:

c#

websocket

I have two C# programs that should communicate over WebSockets the server is working perfectly (also using Alchemy) and has been for a while now (with javascript clients). However connecting an Alchemy WebSocketClient results in an NullReferenceException being thrown on the client side.

After some debugging I found that the exception is thrown on line 187 of WebSocketClient.cs because of the _context.Connection.Connected call. The _context.Connection is the same instance as the local _client and neither of those are null at that point in time. On the TcpClient.Connected page on msdn.microsoft.com there are no possible exceptions listed (indicating to me that it shouldn't throw any exceptions).

Going further back I noticed that the _client class variable is changed on line 176 of WebSocketClient.cs from a normal looking instance to an instance filled with exceptions:

BEFORE LINE 176 Before line 176

AFTER LINE 176 After line 176

Right after this line the Dispose() method of the Context that was just added on line 187 gets called disconnecting the Connection (which is the same instance as the _client that I mentioned before on line 131 of Context.cs.

My question is: Why is this happening and how can I stop it from happening and successfully connect to the desired WebSocketServer?

If you need any more information please don't hesitate to ask me in the comments.

EDIT 1

The exception only occurs when the server is actually listening, if the server is inactive line 176 of WebSocketClient.cs is not reached (this is the correct behavior because OnRunClient() is called when the connection to the server is made).

EDIT 2

As requested the StackTrace:

System.NullReferenceException was unhandled
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=System
  StackTrace:
       at System.Net.Sockets.TcpClient.get_Connected()
       at Alchemy.WebSocketClient.SetupContext(Context context) in C:\...\Alchemy\WebSocketClient.cs:regel 187
       at Alchemy.WebSocketClient.HandleClientThread() in C:\...\Alchemy\WebSocketClient.cs:regel 94
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
like image 329
Manuel Avatar asked Nov 21 '13 13:11

Manuel


1 Answers

As I see you use TcpClient. This class uses Socket class for data transfer (TcpClient has such field). As far as I know in some cases this field can be null. Property Connected of TcpClient uses Connected property of inner Socket instance. Something like this:

public bool Connected 
{
    get 
    {
         return _socket.Connected; // Possible NullRef here!!!
    }
} 

So when this field is null you will get NullReferenceException. As far as I know this might happen when connection was not successfully established.

For example I see this in your code:

try
{
     _client.EndConnect(result);
}
catch (Exception ex)
{
     Disconnect();
     connectError = true;
}

using (_context = new Context(null, _client))
{
      _context = new Context(null, _client);
      _context.BufferSize = 512;
      // some code
}

If connection goes wrong you will get an exception and will do some actions, but in this case your _client will have not initialized Socket field inside. In Context constructor you will try to use it field (in Connected property) and you will get NullReferenceException.

I guess you need to add return in catch block.

OR

Check underlying property Client of your TcpClient (http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcpclient.client(v=vs.110).aspx) like this:

if (_client.Client != null && _client.Connected)
{
    // do what you need
}

Hope this will help you.

like image 197
Tony Avatar answered Oct 04 '22 00:10

Tony