我正在开发一个客户端,该客户端使用网络服务来获取一些事件推送 - 网络服务的设计是这样的,在客户端发布订阅命令时,它会发回一些感兴趣的事件并继续这样做,只要客户端保持连接。
发布命令时,服务会(立即)以带有这些标头的初始答案进行响应
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
然后保持连接打开直到超时(30秒后,如果客户端没有发送一些保持活动的数据)
由于它是 POST + 必须读取响应 + 保持连接打开直到 endOFStream 的混合,看来我必须使用 HttpWebRequest 和 BeginGetRequestStream(到 POST)和 BeginGetResponse 来读取响应并采取行动。
我的问题是 BeginGetResponse 回调直到输入流被服务器/服务实际关闭(30 秒后)才被调用,尽管 AllowReadStreamBuffering 被设置为 false。
文档在 AllowReadStreamBuffering 上有这样的说法:
AllowReadStreamBuffering 属性影响何时调用 BeginGetResponse 方法的回调。当 AllowReadStreamBuffering 属性为 true 时,将在整个流下载到内存后引发回调。当 AllowReadStreamBuffering 属性为 false 时,一旦流可用于读取(可能在所有数据到达之前),就会引发回调。
我已经看到一些建议,无论 AllowReadStreamBuffering 设置为什么,HttpWebRequest 在缓冲区填满之前都不会调用 BeginGetResponse - 但我无法在文档中找到任何内容。
有没有人知道如何控制这种缓冲行为或者建议我在处理这种网络服务时应该尝试的另一种方法?
我目前使用的相关代码片段,如下所示:
public void open()
{
string url = "http://funplaceontheinternet/webservice";
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.Credentials = new NetworkCredential("username", "password");
request.CookieContainer = new CookieContainer();
request.AllowReadStreamBuffering = false;
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
void GetRequestStreamCallback(IAsyncResult result)
{
Debug.WriteLine("open.GetRequestStreamCallback");
HttpWebRequest webRequest = (HttpWebRequest)result.AsyncState;
// End the stream request operation
Stream postStream = webRequest.EndGetRequestStream(result);
// Create the post data
byte[] byteArray = Encoding.UTF8.GetBytes(_xmlEncodedSubscribeCommand);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
webRequest.BeginGetResponse(new AsyncCallback(BeginGetResponseCallback), webRequest);
}
void BeginGetResponseCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = null;
if (request != null)
response = (HttpWebResponse)request.EndGetResponse(result);
else
Debug.WriteLine("request==null :-(");
if (response != null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Debug.WriteLine("BeginGetResponseCallback - received: " + line);
}
Debug.WriteLine("BeginGetResponseCallback - reader.EndOfStream");
}
}
else
Debug.WriteLine("response==null :-(");
}