gpt4 book ai didi

c# - HttpWebRequest,直到 endOfStream 才调用 BeginGetResponse

转载 作者:行者123 更新时间:2023-11-30 13:02:16 28 4
gpt4 key购买 nike

我正在使用一个使用 web 服务来推送一些事件的客户端 - web 服务的设计是这样的,即在客户端发布订阅命令时,它会发回一些感兴趣的事件并继续这样做只要客户端保持连接。

当 POST 命令时,服务会(立即)响应这些 header 的初始答案

Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

然后保持连接打开直到超时(30 秒后,如果客户端没有发送一些保持事件数据)

由于它是 POST + 必须读取响应 + 保持连接打开直到 endOFStream 的混合体,看来我必须将 HttpWebRequest 与 BeginGetRequestStream(到 POST)和 BeginGetResponse 一起使用来读取响应并根据响应执行操作。

我的问题是,尽管 AllowReadStreamBuffering 被设置为 false,但直到输入流被服务器/服务实际关闭(30 秒后),BeginGetResponse 回调才会被调用。

文档在 AllowReadStreamBuffering 上是这样说的:

The AllowReadStreamBuffering property affects when the callback from BeginGetResponse method is called. When the AllowReadStreamBuffering property is true, the callback is raised once the entire stream has been downloaded into memory. When the AllowReadStreamBuffering property is false, the callback is raised as soon as the stream is available for reading which may be before all data has arrived.

我看到了一些建议,无论 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 :-(");
}

最佳答案

您提到该服务是一个网络服务,但没有提到哪个平台。如果这是一个“正常”的 Web 服务,那么我假设 XML 是传输格式。

如果是这样,我怀疑问题可能在于这种通信方式并不真正适合流式传输。在所有数据可用之前,服务器端的 Web 服务基础结构可能不会创建 SOAP 信封和负载。如果您想像这样流式传输,最好在服务器端使用一些自定义服务,而不是 Web 服务。

您确定服务器确实在流式传输响应吗? (例如用 wireshark 之类的东西确认?)

如果你真的想使用网络服务,那么我建议你在第一个事件可用时完成请求,不要等待超时。这仍将实现我假设您正在尝试获得的延迟减少。

关于c# - HttpWebRequest,直到 endOfStream 才调用 BeginGetResponse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15877239/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com