Relationship between HttpContext & HttpConnection - http

Does a HttpContext always have only one HttpConnection? When I execute a request, does it maintain only one HttpConnection even though there may be multiple socket connections due to redirects etc.?

HttpContext always refers to the current or the last connection used by the HTTP exchange regardless of how many intermediate connection may have been employed in the course of the exchange. Connection re-use and pooling is a responsibility of the connection manager.

Related

What does HttpClient do in face of concurrent request exactly at the same time?

As we know it's best practice to use HttpClient in a shared state (Singletone) in Dotnet core instead of creating and dispose of it for each request. We do it to prevent the Port Exhaustion problem.(More Info here).
My problem is What does HttpClient do in face of concurrent requests exactly at the same time when it is shared?
For Example, assume that Request A and Request B sent to a shared HttpClient object at the same time.
my first assumption about its behavior is that it keeps request A and B in a queue and insert them in a row and run A then Run B!
My second assumption is that it uses two peripheral ports (with 2 internal thirds) and answer both of them at the same time.
Is any of this assumption correct? If no Any other Idea?
It's safe to say that your first assumption is incorrect and the second assumption is closer to the truth. each HttpClient instance manages its own connection pool to execute requests concurrently with int.MaxValue as a default value for the number of concurrent connections per server.
Meaning that HttpClient will execute all requests concurrently. Every time you send a new request it'll try to use an existing connection to the server (if it's not in use) otherwise it'll open a new connection to execute the request.
There's an excellent article explaining this in details here:
https://www.stevejgordon.co.uk/httpclient-connection-pooling-in-dotnet-core

How WCF with basic binding over TCP is not reliable?

Since i had bad introduction that confused people, I am editing the question and removing the introduction I previously made.
Now, here is the business case for which now I have concerns. C# pseudocode:
Array.ForEach(files, filename =>
{
try
{
WcfServiceClient wcfClient = new WcfServiceClient();
wcfClient.SomeMethodWhichPostsFile(filename);
}
catch (Exception ex)
{
LogException(ex)
}
}
);
I am confused because of existence of WSBinding which is reliable, and basicHTTPBinding is not. I know that WSBinding with reliable sessions guarantees delivery, order, content is encrypted etc. But in the case I described with pseudocode, according to my opinion I have all of these supported even with basicHttpBinding and HTTPS over TCP. TCP provides me reliability, order guarantees and HTTPS encryption.
(1. is removed) Am I right related to previous? Or to rephrase: is there an example to show that basicHttpBindind under specified conditions can not provide the same features as WS binding with reliable sessions?
My business case requires to accept WCF calls by the order they are issued. If I send them synchronously from the client in a foreach loop (as shown in pseudo code), I assume the order at the server is guaranteed regardless if those are sent within one TCP connection or not, since I am waiting for the response and then I send another request. Even loadbalancer can not disorder messages here since there is no parallelization, messages are sent one by one synchronously.
I assume disordering could happen only if I send messages without waiting for response in fire and forget manner and I use different TCP connections.
So, am I right here? :)
There are different meanings of the term reliability and the interpretation also depends on the context. Your interpretation of reliability in your question is message is delivered. The interpretation of reliability in the source you cite is instead message is delivered exactly once. Your confusion comes from taking the statement "HTTP is not reliable" which was meant for one interpretation of reliability and using it in the your different interpretation of reliability.
HTTP cannot guarantee that the message gets only delivered once, it can at most guarantee that the message is delivered at least once. It can happen that the underlying TCP connection breaks while sending the request or receiving the response. In this case the client might ignore the problem or retry, which might result in no message delivered (ignoring errors while sending request) but also the same message delivered multiple times (retrying if connections breaks during response). By retrying until the response is received successfully one can guarantee that the message is received at least once, which is your interpretation of reliability but not the one from the statement you cite.

TCP sessions with gRPC

Sorry if this question is naive. (gRPC novice here). But, I would like to understand this.
Let's say I have a gRPC service definition like this:
service ABC {
// Update one or more entities.
rpc Write(WriteRequest) returns (WriteResponse) {
}
// Read one or more entities.
rpc Read(ReadRequest) returns (stream ReadResponse)
{
}
// Represents the bidirectional stream
rpc StreamChannel(stream StreamMessageRequest)
returns (stream StreamMessageResponse) {
}
}
Our potential use case would be the server built using C++ and the client using Java. (Not sure is that matters).
I would like to understand how the TCP sessions are managed. The Stream Channel would be used for constant telemetry data streaming between the client and the server. (Constant data transfer, but the bulk from the server to the client).
Does the StreamChannel have a separate TCP session, while for every Write and Read a new session would be established and terminated after the call is done?
Or is there a single TCP session over which all the communication happens?
Again, please excuse me if this is very naive.
Thanks for your time.
Since gRPC uses HTTP/2, it can multiplex multiple RPCs on the same TCP connection. The Channel abstraction in gRPC lets gRPC make connection decisions without the application needing to be strongly-aware.
By default, gRPC uses the "pick first" load balancing policy, which will use a single connection to the backend. All new RPCs would go over that connection.
Connections may die (due to I/O failures) or need to be shut down (various reasons), so gRPC handles reconnecting automatically. Because it can take a very long time to shut down a connection (as gRPC waits for RPCs on that connection to complete), it's still possible that gRPC would have 2 or more connections to the same backend.
So for your case, all the RPCs would initially exist on the same connection. As time goes on new RPCs may use a newer connection, and an old, long-lived StreamChannel RPC may keep the initial TCP connection alive. If that long-lived StreamChannel is closed and re-created by the application, then it could share the newer connection again.
I also posted the same question in grpc.io, and the response I got was inline with the marked answer.
Summary:
If there is no load-balancing, all the RPCs use the same session. The session remains connected across requests. The session establishment happens the first time a call is attempted on the channel.

how does ASP.net "HttpResponse.IsClientConnected" work?

if HTTP is connection-less, how does ASP.net response property, HttpResponse.IsClientConnected detect client is connected or not?
HTTP is not "connection-less" - you still need a connection to receive data from the server; more correctly, HTTP is stateless. Applications running on-top of HTTP will most likely actually be stateful, but HTTP itself is not.
"Connectionless" can also refer to a system using UDP as the transport instead of TCP. HTTP primarily runs over TCP and pretty much every real webserver expects, and returns, TCP messages instead of UDP. You might see HTTP-like traffic in UDP-based protocols like UPnP, but because you want your webpage to be delivered reliably, TCP will always be used instead of UDP.
As for IsClientConnected, when you access that property it calls into the current HttpWorkerRequest which is an abstract class implemented by the current host environment.
IIS7+ implements it such that if it previously received a TCP disconnect message (that sets a field) the method would now return false.
The ISAPI implementation (IIS 6) instead calls into a function within IIS that informs the caller if the TCP client on the current request/response context is still connected, though presumably it works on the same basis: when the webserver receives a TCP timeout, disconnect or connection-reset message it sets a flag and lets execution continue instead of terminating the response-generator thread.
Here's the relevant source code:
HttpResponse.IsClientConnected: http://referencesource.microsoft.com/#System.Web/HttpResponse.cs,80335a4fb70ac25f
IIS7WorkerRequest.IsClientConnected: http://referencesource.microsoft.com/#System.Web/Hosting/IIS7WorkerRequest.cs,1aed87249b1e3ac9
ISAPIWorkerRequest.IsClientConnected: http://referencesource.microsoft.com/#System.Web/Hosting/ISAPIWorkerRequest.cs,f3e25666672e90e8
It all starts with an HTTP request. Inside it, you can, for example, spawn worker threads, that can outlive the request itself. Here is where IsClientConnected comes in handy, so that the worker thread knows that the client has already received the response and disconnected or not.

There is some way to guarantee an unique (not pooled) database connection per user session in ASP.NET?

Due to locking concerns, we need to guarantee that every asp.net session get it's own connection in the connection pool. One connection per session, not shared by any other connection.
Any ideas?
There is no RIGHT answer, we are just out of ideas and need some suggestions.
Thanks in advance.
If this is SQL Server, in the database connection string add Pooling='false' and then connections will not pooled.
In general connection pooling is good for your application. Open, do something, close and dispose of the connection back to the pool. I've had instances where the connections were not being disposed of properly which caused issues.
Make sure all connections are in a using block (which will call dispose automatically) or if they are in a try catch, make sure in finally dispose is called on the connection.
Other than that, if pooling is not desired, alter the connection string not to use the pool.

Resources