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
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With