-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Use generated PInvokes and exchange types #50685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b2281ab
99b0e19
b0c94a1
ff71d9e
0469c47
d716113
7704525
da3c8ca
ebbce1f
9f66273
933163e
9d8bae5
d4d3ed9
bb77b1b
f9ad985
b9e4eea
09966ae
96374de
abd69e6
a2fdb9e
7f054db
31e3a17
7635285
4ffc99c
ab1a83b
0cba7ef
a3d4608
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,89 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Net.WebSockets; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace TestClient | ||
namespace TestClient; | ||
|
||
public class Program | ||
{ | ||
public class Program | ||
private const string Address = | ||
"http://localhost:5000/public/1kb.txt"; | ||
// "https://localhost:9090/public/1kb.txt"; | ||
|
||
public static void Main(string[] args) | ||
{ | ||
private const string Address = | ||
"http://localhost:5000/public/1kb.txt"; | ||
// "https://localhost:9090/public/1kb.txt"; | ||
Console.WriteLine("Ready"); | ||
Console.ReadKey(); | ||
|
||
public static void Main(string[] args) | ||
{ | ||
Console.WriteLine("Ready"); | ||
Console.ReadKey(); | ||
var handler = new HttpClientHandler(); | ||
handler.MaxConnectionsPerServer = 500; | ||
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; | ||
// handler.UseDefaultCredentials = true; | ||
HttpClient client = new HttpClient(handler); | ||
|
||
var handler = new HttpClientHandler(); | ||
handler.MaxConnectionsPerServer = 500; | ||
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; | ||
// handler.UseDefaultCredentials = true; | ||
HttpClient client = new HttpClient(handler); | ||
RunParallelRequests(client); | ||
|
||
RunParallelRequests(client); | ||
// RunManualRequests(client); | ||
|
||
// RunManualRequests(client); | ||
// RunWebSocketClient().Wait(); | ||
|
||
// RunWebSocketClient().Wait(); | ||
Console.WriteLine("Done"); | ||
// Console.ReadKey(); | ||
} | ||
|
||
Console.WriteLine("Done"); | ||
// Console.ReadKey(); | ||
private static void RunManualRequests(HttpClient client) | ||
{ | ||
while (true) | ||
{ | ||
Console.WriteLine("Press any key to send request"); | ||
Console.ReadKey(); | ||
var result = client.GetAsync(Address).Result; | ||
Console.WriteLine(result); | ||
} | ||
} | ||
|
||
private static void RunManualRequests(HttpClient client) | ||
private static void RunParallelRequests(HttpClient client) | ||
{ | ||
int completionCount = 0; | ||
int iterations = 100000; | ||
for (int i = 0; i < iterations; i++) | ||
{ | ||
while (true) | ||
{ | ||
Console.WriteLine("Press any key to send request"); | ||
Console.ReadKey(); | ||
var result = client.GetAsync(Address).Result; | ||
Console.WriteLine(result); | ||
} | ||
client.GetAsync(Address) | ||
.ContinueWith(t => Interlocked.Increment(ref completionCount)); | ||
} | ||
|
||
private static void RunParallelRequests(HttpClient client) | ||
while (completionCount < iterations) | ||
{ | ||
int completionCount = 0; | ||
int iterations = 100000; | ||
for (int i = 0; i < iterations; i++) | ||
{ | ||
client.GetAsync(Address) | ||
.ContinueWith(t => Interlocked.Increment(ref completionCount)); | ||
} | ||
|
||
while (completionCount < iterations) | ||
{ | ||
Thread.Sleep(10); | ||
} | ||
Thread.Sleep(10); | ||
} | ||
} | ||
|
||
public static async Task RunWebSocketClient() | ||
{ | ||
ClientWebSocket websocket = new ClientWebSocket(); | ||
|
||
string url = "ws://localhost:5000/"; | ||
Console.WriteLine("Connecting to: " + url); | ||
await websocket.ConnectAsync(new Uri(url), CancellationToken.None); | ||
|
||
public static async Task RunWebSocketClient() | ||
string message = "Hello World"; | ||
Console.WriteLine("Sending message: " + message); | ||
byte[] messageBytes = Encoding.UTF8.GetBytes(message); | ||
await websocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None); | ||
|
||
byte[] incomingData = new byte[1024]; | ||
WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment<byte>(incomingData), CancellationToken.None); | ||
|
||
if (result.CloseStatus.HasValue) | ||
{ | ||
Console.WriteLine("Closed; Status: " + result.CloseStatus + ", " + result.CloseStatusDescription); | ||
} | ||
else | ||
{ | ||
ClientWebSocket websocket = new ClientWebSocket(); | ||
|
||
string url = "ws://localhost:5000/"; | ||
Console.WriteLine("Connecting to: " + url); | ||
await websocket.ConnectAsync(new Uri(url), CancellationToken.None); | ||
|
||
string message = "Hello World"; | ||
Console.WriteLine("Sending message: " + message); | ||
byte[] messageBytes = Encoding.UTF8.GetBytes(message); | ||
await websocket.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None); | ||
|
||
byte[] incomingData = new byte[1024]; | ||
WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment<byte>(incomingData), CancellationToken.None); | ||
|
||
if (result.CloseStatus.HasValue) | ||
{ | ||
Console.WriteLine("Closed; Status: " + result.CloseStatus + ", " + result.CloseStatusDescription); | ||
} | ||
else | ||
{ | ||
Console.WriteLine("Received message: " + Encoding.UTF8.GetString(incomingData, 0, result.Count)); | ||
} | ||
Console.WriteLine("Received message: " + Encoding.UTF8.GetString(incomingData, 0, result.Count)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,7 +3,6 @@ | |||||||||
|
||||||||||
using System.Diagnostics; | ||||||||||
using System.Threading.Tasks.Sources; | ||||||||||
using Microsoft.AspNetCore.HttpSys.Internal; | ||||||||||
|
||||||||||
namespace Microsoft.AspNetCore.Server.HttpSys; | ||||||||||
|
||||||||||
|
@@ -39,9 +38,9 @@ internal ValueTask<RequestContext> AcceptAsync() | |||||||||
|
||||||||||
AllocateNativeRequest(); | ||||||||||
|
||||||||||
uint statusCode = QueueBeginGetContext(); | ||||||||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && | ||||||||||
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) | ||||||||||
var statusCode = QueueBeginGetContext(); | ||||||||||
if (statusCode != ErrorCodes.ERROR_SUCCESS && | ||||||||||
statusCode != ErrorCodes.ERROR_IO_PENDING) | ||||||||||
{ | ||||||||||
// some other bad error, possible(?) return values are: | ||||||||||
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED | ||||||||||
|
@@ -55,16 +54,16 @@ private void IOCompleted(uint errorCode, uint numBytes) | |||||||||
{ | ||||||||||
try | ||||||||||
{ | ||||||||||
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && | ||||||||||
errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) | ||||||||||
if (errorCode != ErrorCodes.ERROR_SUCCESS && | ||||||||||
errorCode != ErrorCodes.ERROR_MORE_DATA) | ||||||||||
{ | ||||||||||
_mrvts.SetException(new HttpSysException((int)errorCode)); | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
Debug.Assert(_requestContext != null); | ||||||||||
|
||||||||||
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) | ||||||||||
if (errorCode == ErrorCodes.ERROR_SUCCESS) | ||||||||||
{ | ||||||||||
var requestContext = _requestContext; | ||||||||||
// It's important that we clear the request context before we set the result | ||||||||||
|
@@ -79,10 +78,10 @@ private void IOCompleted(uint errorCode, uint numBytes) | |||||||||
AllocateNativeRequest(numBytes, _requestContext.RequestId); | ||||||||||
|
||||||||||
// We need to issue a new request, either because auth failed, or because our buffer was too small the first time. | ||||||||||
uint statusCode = QueueBeginGetContext(); | ||||||||||
var statusCode = QueueBeginGetContext(); | ||||||||||
|
||||||||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && | ||||||||||
statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) | ||||||||||
if (statusCode != ErrorCodes.ERROR_SUCCESS && | ||||||||||
statusCode != ErrorCodes.ERROR_IO_PENDING) | ||||||||||
{ | ||||||||||
// someother bad error, possible(?) return values are: | ||||||||||
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED | ||||||||||
|
@@ -117,14 +116,14 @@ private uint QueueBeginGetContext() | |||||||||
_requestContext.RequestId, | ||||||||||
// Small perf impact by not using HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY | ||||||||||
// if the request sends header+body in a single TCP packet | ||||||||||
(uint)HttpApiTypes.HTTP_FLAGS.NONE, | ||||||||||
0u, | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels like a small loss in code quality. Is there not a "none" flag in the httpsys headers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, there isn't. There isn't one defined natively either.
|
||||||||||
_requestContext.NativeRequest, | ||||||||||
_requestContext.Size, | ||||||||||
&bytesTransferred, | ||||||||||
_overlapped); | ||||||||||
|
||||||||||
if ((statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_CONNECTION_INVALID | ||||||||||
|| statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER) | ||||||||||
if ((statusCode == ErrorCodes.ERROR_CONNECTION_INVALID | ||||||||||
|| statusCode == ErrorCodes.ERROR_INVALID_PARAMETER) | ||||||||||
&& _requestContext.RequestId != 0) | ||||||||||
{ | ||||||||||
// ERROR_CONNECTION_INVALID: | ||||||||||
|
@@ -139,15 +138,15 @@ private uint QueueBeginGetContext() | |||||||||
_requestContext.RequestId = 0; | ||||||||||
retry = true; | ||||||||||
} | ||||||||||
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) | ||||||||||
else if (statusCode == ErrorCodes.ERROR_MORE_DATA) | ||||||||||
{ | ||||||||||
// the buffer was not big enough to fit the headers, we need | ||||||||||
// to read the RequestId returned, allocate a new buffer of the required size | ||||||||||
// (uint)backingBuffer.Length - AlignmentPadding | ||||||||||
AllocateNativeRequest(bytesTransferred); | ||||||||||
retry = true; | ||||||||||
} | ||||||||||
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS | ||||||||||
else if (statusCode == ErrorCodes.ERROR_SUCCESS | ||||||||||
&& HttpSysListener.SkipIOCPCallbackOnSuccess) | ||||||||||
{ | ||||||||||
// IO operation completed synchronously - callback won't be called to signal completion. | ||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.