[英]How to call UWP function from ASP.NET Core 2.1 in Windows 10 IoT Core for Raspberry PI 3
[英]StreamSocketListener randomly receive empty from client on Raspberry Pi 3 (IoT Core UWP)
我正在測試一個非常簡單的Web服務器代碼(可以從MSDN示例中復制它,也可以從我忘記的地方復制),我正在Raspberry Pi 3 Model B上使用IoT Core v.10.0.16299.309運行它。 我做了一切正確的事情,包括在每個請求上都放置了套接字,並且代碼在大多數情況下都起作用。
我只有一個客戶端,每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
IInputStream.ReadAsync()文檔提供了一些有趣的信息,這些信息可能會有所幫助:
始終從IAsyncOperationWithProgress(IBuffer,UInt32)返回的緩沖區中讀取數據。 不要假設輸入緩沖區包含數據。 根據實現的不同,讀取的數據可能會放置在輸入緩沖區中,或者可能會在其他緩沖區中返回。 對於輸入緩沖區,您不必實現IBuffer接口。 相反,您可以創建Buffer類的實例。
提供的緩沖區可能不包含數據。
您可以使用返回緩沖區並從中提取數據,也可以使用DataReader.ReadBuffer() (或您的情況下的DataReader.ReadString() )從流中獲取數據。
通常,使用DataReader從流中讀取數據比使用低級API更容易。
您的代碼成為
byte[] data = new byte[_bufferSize];
IBuffer buffer = data.AsBuffer();
uint bytesRead = _bufferSize;
while (bytesRead == _bufferSize)
{
var readFromStreamBuffer = await input.ReadAsync(buffer, _bufferSize, InputStreamOptions.Partial);
var readBytes = readFromStreamBuffer.ToArray();
request.Append(Encoding.UTF8.GetString(readBytes, 0, readBytes.Length));
bytesRead = readFromStreamBuffer.Length;
}
byte[] data = new byte[_bufferSize];
IBuffer buffer = data.AsBuffer();
uint bytesRead = _bufferSize;
var dataReader = new DataReader(input);
while (bytesRead == _bufferSize)
{
await dataReader.LoadAsync(_bufferSize);
var readFromStreamBuffer = dataReader.ReadBuffer();
var readBytes = readFromStreamBuffer.ToArray();
request.Append(Encoding.UTF8.GetString(readBytes, 0, readBytes.Length));
bytesRead = readFromStreamBuffer.Length;
}
byte[] data = new byte[_bufferSize];
IBuffer buffer = data.AsBuffer();
uint bytesRead = _bufferSize;
var dataReader = new DataReader(input);
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
while (bytesRead == _bufferSize)
{
await dataReader.LoadAsync(_bufferSize);
request.Append(dataReader.ReadString(dataReader.UnconsumedBufferLength));
bytesRead = readFromStreamBuffer.Length;
}
出於種種主意,我將代碼更改為改為使用Socket.InputStream.AsStreamForRead(),然后使用.ReadLineAsync()只是讀取第一行以進行測試。 它似乎很穩定,經過12個小時以上,沒有一個空的請求!!!
對於我所需要的,這實際上很好,因為我並沒有真正構建一個功能齊全的Web服務器,因此我不需要獲得完整的請求。 我需要做的就是獲取HTTP GET QueryString並將參數傳遞給Raspberry Pi的GPIO。
正如Vincent所建議的,.ReadAsync()具有一些非常有趣的行為。 我一定會再嘗試他的建議。
public async void HandleRequest(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
string requestString;
try
{
Stream inStream = args.Socket.InputStream.AsStreamForRead();
StreamReader reader = new StreamReader(inStream);
requestString = await reader.ReadLineAsync();
// Some other code here to process the request object
// and respond it back to the client. They are irrelevant
} // catch
catch (Exception ex)
{
// Log here
}
finally
{
args.Socket.Dispose();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.