Although HTTP is a stateless protocol, there's this PushStreamContent class that facilitates server-sent events, as you can read here. A Web API implementation may store client streams and periodically send push updates. However, it's a bit of a problem to detect when the client disconnects.
In this discussion, Henrik Nielsen states that:
Detecting that the TCP connection has been reset is something that the Host (ASP, WCF, etc.) monitors but in .NET 4 neither ASP nor WCF tells us (the Web API layer) about it. This means that the only reliable manner to detect a broken connection is to actually write data to it. This is why we have the try/catch around the write operation in the sample. That is, responses will get cleaned up when they fail and not before.
In .NET 4.5 there is a mechanism for detecting client disconnect but I haven't tried it out.
Fast forward two and a half years to today. Does anyone have any idea what this mechanism is, and whether it works?
An interesting response was post on this link : link to the article
this is a part of the answer
In .NET 4.5 there is a mechanism for detecting client disconnect but I haven't tried it out.
This (simplified) code works for me:
public HttpResponseMessage Get(HttpRequestMessage request)
{
// Register for client disconnect notifications
object clientId = ...; // this is the object passed to the callback
System.Web.HttpContext.Current.Response.ClientDisconnectedToken.Register(
delegate (object obj)
{
// Client has cleanly disconnected
// obj is the clientId passed in to the register
// handle client disconnection
//...
}
, clientId );
// Normal code from the sample continues
response.Content = new PushStreamContent(...);
}
The ClientDisconnect callback is called back if e.g. you close the client browser page cleanly, but if you pull the network cable out, it does not get notified. So for this unclean disconnection, we still need some other way of detecting this, such as monitoring failures during the timer callback.
Related
I am hoping someone can point me in the right direction. I have a CF2021 Server which uses a Node.js websocket server and CF pages (via javascript) as a client. Messages from user to user work as expected, so no issue there.
This CF Server also has a custom API built using CFML that handles and routes inbound SMS messages. My question is; what would be the best way to send the SMS message (by now its json) to the Node.js websocket to it can send it to the user(s).
I tried using the same javascript that the browser client uses, but it appears that the CFML API script is "browser-less", so that doesn't work, or should it?
I thought something like Apache Groovy may be the solution, but I am having difficulties with any websocket example I have found.
Any suggestions would be greatly appreciated.
thanks in advance
Flow matters.
If you want to handle an incoming message by delivering it to all currently logged in users who are subscribed to messages of the current sort: set up your message handler to deliver using lucee/adobe-coldfusion websockets. Be forewarned, Lucee takes some setup time, but once running, it is a great solution.
If you don't need immediate delivery, or you need a super simple solution: I actually have had some success with "Long Polling" you just have to remember to use "flush" early in the request, before any pause/sleep, then loop your message lookup requests for new data, with a 1-5 second delay between each loop. Once new data is found, I like to return the request to the client, close that polling request and start a new polling request using the client side. I typically won't poll for more than 60 seconds. Even if the returned json object is empty.
I'm new on .NET technology and come into some problem. Currenlty i'm trying to build a REST API that handle long processing before sending the result to client.
What i'm trying to achieve is, i would like to do a background processing after receiving request from client. But, i would also like to send a response to client.
In short, it would be something like this.
Client Request -> Handled by controller ( doing some processing ) -> send response directly, ignoring the background that still running.
On Java, i can do this using Runnable Thread. How can i achieve this on C# Web API ?
Thank you.
In short, don't do this.
The job of an API is not to perform heavy duty, long running tasks.
You could simply let the API receive the request to perform something, then delegate that to another service. The API can then send a 200 response to show it received the request and maybe a URL to another resource which allows a user to track the progress.
The API needs to be available and responsive at all times. It needs to serve a number of users and if a number of them all request something that uses a lot of resources and takes a lot of time, chances are the API will simply go down and not serve anyone.
This is why you do not do such things in an API. Let other services do the heavy lifting.
Your api can call another async method and return 200/OK response without waiting for the request to complete.
You can learn more about async programing in c#.
static async Task Main(string[] args)
{
Console.WriteLine("coffee is ready");
var toastTask = MakeToastWithButterAndJamAsync(2);
async Task<Toast> MakeToastWithButterAndJamAsync(int number)
{
//Do something here.
}
}
This can be achieve this using loosed coupled architecture, by introducing service bus or blob storage, once you receive request in web api you can save it to blob/service bus and return acknowlegement response from web api. From service bus/blob storage use webjob/function/ durable function app to process the message using event.
I've been looking into using websockets with the Suave web server. Unfortunately, it's not very well documented, and all I've managed to find was this: https://github.com/SuaveIO/suave/tree/master/examples/WebSocket
However, that only shows the websocket responding to the client that made the request, and I want to basically have the socket respond to all connected clients. Something like a chat server.
I've used SignalR in the past, but would prefer to avoid it for this.
So, how would I go about having the Suave server send data to all connected websocket clients?
Suave doesn't provide anything like that out of the box, however you can easily extend the example to do so.
The socket handler ws passed to the handShake function can pass the client information outside, and you can build a send/broadcast API around it.
The ws function can be modified for example like this
let ws onConnect onDisconnect (webSocket: WebSocket) (context: HttpContext) =
let loop () = (* the socket logic stays the same *)
socket {
onConnect webSocket context
try
do! loop ()
finally
onDisconnect context
}
Then it's up to you to inject the onConnect and onDisconnect handles to register/unregister clients.
I use a MailboxProcessor to serialize the Connect/Disconnect/Send operations, alternatively it's easy to use Reactive Extensions, or a shared mutable concurrent storage like ConcurrentDictionary...
I would like to research a technique for building Web API methods but I am having trouble looking up information on it partly because I do not know what the technique is called. The idea is that instead of the client polling the web API on a tight loop and taking action when the response data changes, instead the server holds the call open until it sees the data change and then completes the request. This is more efficient because less time is spent making web connections as each call from the client is utilized to it's full extent: if new data is available before the web API call's timeout is reached then the call can immediately return that new data.
What is this technique called?
Long polling. Not tried it myself yet.
http://en.wikipedia.org/wiki/Push_technology#Long_polling
I'm building a Grails app which queries several API's across the Web. The problem is that this queries are very time consuming and it is really annoying for the user to click one button and wait so much time without nothing changes in the page.
The basic architecture of my app is, when the user clicks the button, the client side performs an Ajax request with Prototype library to the server side. The server side, then, connects to the Last.fm API and retrieve a list of events. When the server side is finished populating the list with events it sends a JSON response to the client side which allows the client side to create markers for each event on a Google map.
What I want to achieve is, instead of waiting for all the events being retrieved from the API to send the JSON response, the server side sends a JSON response as soon as it retrieve one event, allowing the client side to populate the map while other events are yet being retrieved.
Any ideas how can I implement this? I read about the concept of Ajax Push but I'm not sure if it is what I need.
Thanks for the help!
There is no way to open a listening connection on the client that your server might connect to. Instead, what you need is a connection to the server that is kept alive and can be used to receive events. This way, you could directly return the "action" request and inform the client through your persistent event connection once the last.fm request was completed.
That said, the way I would implement is using ajax keep alive.
Take a look at cometd plugin.