我正在使用一个使用web服务的客户端来推送一些事件 - webservice就是这样设计的,在客户端POST一个订阅命令后,它会发回一些感兴趣的事件并继续这样做只要客户保持联系。
在发布命令时,服务会立即响应这些标题的初始答案
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
然后保持连接打开,直到超时(30秒后,如果客户端没有发送一些保持活动数据)
由于它是POST +必须读取响应+保持连接打开直到endOFStream的混合,看来我必须使用HttpWebRequest和BeginGetRequestStream(对POST)和BeginGetResponse来读取并对响应进行操作。
我的问题是,直到服务器/服务实际关闭输入流(30秒后)才会调用BeginGetResponse回调,尽管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 :-(");
}
答案 0 :(得分:0)
您已经提到该服务是一项Web服务,但不是哪个平台。 如果这是"正常" Web服务,然后我假设XML是传输格式。
如果是这样,我怀疑问题可能是这种沟通方式并不真正适合流式传输。在所有数据都可用之前,服务器端的Web服务基础结构可能不会创建SOAP信封和有效负载。如果你想像这样流,你最好在服务器端使用一些自定义服务,而不是Web服务。
您是否确定服务器确实正在流式传输响应? (例如用wireshark之类的东西确认?)
如果您真的想使用网络服务,那么我会建议您在第一个活动可用时完成请求,并且不要等待超时。这仍将实现我假设你想要的延迟减少。