【发布时间】:2018-03-27 14:22:59
【问题描述】:
我正在测试一个非常简单的 Web 服务器代码(从 MSDN 示例或我忘记的某个地方复制它),我在带有 IoT Core v.10.0.16299.309 的 Raspberry Pi 3 Model B 上运行它。我正确地完成了所有工作,包括在每个请求上处理套接字,并且代码大部分时间都有效。
我只有一个客户端,每 30 秒向该 Web 服务发送 3 个非常简单的 HTTP GET 请求,只是一个像这样的简单 URL:http://serverIP/get?id=123 它正确返回结果,但在一小时内随机返回,请求对象为空出于某种奇怪的原因。我不知道为什么。
private StreamSocketListener _listener;
private int _bufferSize = 8192;
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.GetDeferral();
_listener = new StreamSocketListener();
_listener.ConnectionReceived += HandleRequest;
await _listener.BindServiceNameAsync("9080");
}
public async void HandleRequest(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
StringBuilder request = new StringBuilder()
using (IInputStream input = args.Socket.InputStream)
{
byte[] data = new byte[_bufferSize];
IBuffer buffer = data.AsBuffer();
uint bytesRead = _bufferSize;
while (bytesRead == _bufferSize)
{
await input.ReadAsync(buffer, _bufferSize, InputStreamOptions.Partial);
request.Append(Encoding.UTF8.GetString(data, 0, data.Length));
bytesRead = buffer.Length;
// Some other code here to process the request object
// and respond it back to the client. They are irrelevant.
} // while
} // using
} // catch
catch (Exception ex)
{
// Log here
}
finally
{
args.Socket.Dispose();
}
} // method
我认为线程有问题,所以我禁用了大部分异步和等待。有趣的是,结果要好得多。请求对象是 99% 的罚款。 12小时内,只有3-4次请求为空。我认为这不是正确的解决方案......但我真的被困在这个问题上并且无法弄清楚为什么。任何帮助表示赞赏。
private StreamSocketListener _listener;
private int _bufferSize = 8192;
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.GetDeferral();
_listener = new StreamSocketListener();
_listener.ConnectionReceived += HandleRequest;
_listener.BindServiceNameAsync("9080"); // ** No "await"
}
// ** No "async"
public void HandleRequest(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
StringBuilder request = new StringBuilder()
using (IInputStream input = args.Socket.InputStream)
{
byte[] data = new byte[_bufferSize];
IBuffer buffer = data.AsBuffer();
uint bytesRead = _bufferSize;
while (bytesRead == _bufferSize)
{
// ** No "await"
input.ReadAsync(buffer, _bufferSize, InputStreamOptions.Partial);
request.Append(Encoding.UTF8.GetString(data, 0, data.Length));
bytesRead = buffer.Length;
// Some other code here to process the request object
// and respond it back to the client. They are irrelevant.
} // while
} // using
} // catch
catch (Exception ex)
{
// Log here
}
finally
{
args.Socket.Dispose();
}
} // method
【问题讨论】:
-
taskInstance.GetDeferral()- 这将获得一个最终将被 GC 处理的临时对象。当对象被 GC 时,它(可能)会自动完成延迟(有些对象会,有些不会)。您可以尝试保持延迟(例如,在类字段中),然后在完成后明确地Complete它吗? -
嗨,彼得.. 感谢您的回复。想我也试过了,_deferral.Completed() 执行后,StreamSocketListen 将不再监听。如果我注释掉 _deferral.Complete() 但保留类变量,则行为与我描述的完全相同。如果我误解了你的意思,请纠正我。
-
@userb00,你是否在响应的标题中添加了
Connection: close? -
是的,我确实将响应发送为 HTTP/1.1 200 OK,然后是 Content-Length:xxx,然后是 Connection:close
标签: c# uwp raspberry-pi3 windowsiot windows-iot-core-10