常用的HttpClient无法正常接收SSE协议的数据,会出现各种各样的Bug。因此需要使用TcpClient建立长连接来处理SSE协议的数据。
SSE协议数据的返回头中有
Content-Type: text/event-stream; charset=utf-8
这样的数据会持续发送,直到连接关闭。
采用HttpClient无法正常接受这样的数据,部分方法会一直等待直到连接关闭,例如:
HttpClient.SendAsync(); HttpClient.GetAsync(); HttpClient.GetStringAsync();
而
HttpClient.GetStreamAsync()
能正常接受到流,并且可以读取。但是有些时候会不能接受完一波Event的所有数据,直到下一波Event数据才能接收到,用起来会有各种麻烦,比如Json数据不完整,没法正常解析成对象。
因此,兼容SSE得放弃HttpClient,采用TcpClient建立长连接。
按照标准的http协议构造报文,在Stream中发送出去。如果是Https数据,则需要用SslStream包裹从TcpClient获得的NetworkStream即可。
1 using System.IO; 2 using System.Net.Http; 3 using System.Net.Sockets; 4 using System.Text; 5 6 public static void SseSend(string host, int port, string requestMessage) 7 { 8 using var tcp = new TcpClient(); 9 tcp.Connect(host, port); 10 var stream = tcp.GetStream(); 11 12 var requestData = Encoding.UTF8.GetBytes(requestMessage); 13 //发送HTTP请求报文和数据 14 stream.Write(requestData); 15 16 //接收HTTP响应报文和数据 17 var responseBuffer = new byte[1024 * 1024]; 18 var receivedNum = stream.Read(responseBuffer, 0, responseBuffer.Length); 19 }