private void ReceiveCallback(IAsyncResult result)
{
int bytesRead;
NetworkStream stream;
try
{
stream = this.client.GetStream();
bytesRead = stream.EndRead(result);
}
catch
{
return;
}
// EndRead() blocks until data is received, so if we have nothing
// then the connection has been terminated
if (bytesRead == 0)
{
this.IsConnected = false;
if (this.connectionTerminated != null)
{
this.connectionTerminated(this, EventArgs.Empty);
}
return;
}
// Get the data, raise the received event and begin listening again
byte[] buffer = result.AsyncState as byte[];
string data = this.encoding.GetString(buffer, 0, bytesRead);
this.currentDataSet = this.currentDataSet + data;
// If we have received a full payload from the server then handle any pings and despatch to the subscribers
while (this.currentDataSet.Contains("\n"))
{
int delimiterIndex = this.currentDataSet.IndexOf('\n') + 1;
string payload = this.currentDataSet.Substring(0, delimiterIndex);
if (payload.StartsWith("PING", StringComparison.OrdinalIgnoreCase))
{
this.ReplyToPing(payload);
}
if (this.dataReceived != null)
{
if (!payload.StartsWith("PING", StringComparison.OrdinalIgnoreCase))
{
this.dataReceived(this, new DataReceivedEventArgs(payload));
}
}
// If two messages were joined together, then remove the one we just processed and iterate
// otherwise empty the current data set and begin listening again
if (delimiterIndex < this.currentDataSet.Length)
{
this.currentDataSet = this.currentDataSet.Substring(delimiterIndex);
}
else
{
this.currentDataSet = string.Empty;
}
}
stream.BeginRead(buffer, 0, buffer.Length, this.ReceiveCallback, buffer);
}