启用心跳后连接断开导致程序崩溃
bjzycx opened this issue · comments
表现:启用心跳,一段时间后,断开客户端。然后程序会在不存在的连接上试图发送心跳,因为缺少了异常的捕获,导致服务端崩溃,
异常如下:
System.IO.IOException ---> System.Net.HttpListenerException: 企图在不存在的网络连接上进行操作。
在 System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
在 Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.Write(Byte[] buffer, Int32 offset, Int32 count)
--- 内部异常堆栈跟踪的结尾 ---
在 Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.Write(Byte[] buffer, Int32 offset, Int32 count)
在 System.Net.Http.Internal.DelegatingStream.Write(Byte[] buffer, Int32 offset, Int32 count)
在 System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
在 System.IO.StreamWriter.Flush()
在 ServerSentEvent4Net.ServerSentEvent.Client.Send(IMessage msg) 位置 D:\Code\TFS2012\QinQouShui\QouShui\QProtocol\ServerSentEvent4Net\ServerSentEvent.cs:行号 240
在 ServerSentEvent4Net.ServerSentEvent.<>c__DisplayClass24_0.b__0(Client c) 位置 D:\Code\TFS2012\QinQouShui\QouShui\QProtocol\ServerSentEvent4Net\ServerSentEvent.cs:行号 120
在 System.Collections.Generic.List1.ForEach(Action
1 action)
在 ServerSentEvent4Net.ServerSentEvent.SendAndRemoveDisconneced(List`1 clientsToSendTo, Message msg) 位置 D:\Code\TFS2012\QinQouShui\QouShui\QProtocol\ServerSentEvent4Net\ServerSentEvent.cs:行号 120
在 ServerSentEvent4Net.ServerSentEvent.Send(Message msg) 位置 D:\Code\TFS2012\QinQouShui\QouShui\QProtocol\ServerSentEvent4Net\ServerSentEvent.cs:行号 108
修正方法:增加通用异常捕获,修正后的代码如下:
` public void Send(IMessage msg)
{
try
{
// Only send retry once for each connection
if (IsRetrySent)
msg.Retry = null;
var text = msg.ToString();
StreamWriter.WriteLine(text);
StreamWriter.Flush();
if (!Message.IsOnlyComment(msg))
LastMessageId = msg.Id;
if (!string.IsNullOrWhiteSpace(msg.Retry))
IsRetrySent = true;
}
catch (HttpException ex)
{
if (ex.ErrorCode == -2147023667) // The remote host closed the connection.
{
IsConnected = false;
}
}
catch (System.ServiceModel.CommunicationException)
{
IsConnected = false;
}
**catch (IOException ex)
{
//IO异常,可判定为已断开
IsConnected = false;
Console.WriteLine("SSE Send Error:" + GetErr(ex));
}
catch (Exception ex)
{
Console.WriteLine("SSE Send Error:" + GetErr(ex));
}**
}
string GetErr(Exception ex)
{
Exception innerException = ex.InnerException;
string err = ex.Message;
while (innerException != null)
{
err = innerException.Message;
innerException = innerException.InnerException;
}
return err;
}`