Correct configuration of SignalR for long running process - wpf

Scenario: WPF application that sends a file to a server and the server, in turn, performs a series of validations that can take several minutes, during which the server sends a series of messages to tell the application what it is doing (signalr), in at the end of everything, it warns that the process has ended.
What I'm doing: Every time the application is sending a new file I start the hub await hubConnection.Start() and at the end of it all I stop.
The process consists of: doing some local validations, sending the file to the server, monitoring the processing (signalr) and at the end, if applicable, downloading a file with the error;
It's all working fine, but I'm afraid something might go wrong along the way, flag not sending the messages, etc.
My question: What is the correct way to do this? When should I connect the hub (await for hubConnection.Start())? Should I do this when starting the app? How do I receive the messages later (in each message I have an identifier of the file I am working on)?

Related

Is it possible for an ISAPI Extension to disconnect from the client

I developed an ISAPI Extension for IIS in C using VS 2019. A desktop application performs a GET to a URL which triggers the extension.
The business user asked if it is possible for long running tasks if it could return a status & short message to the desktop app and continue processing. The result of the processing is stored in a database.
I tried returning HSE_STATUS_PENDING and running the process in another thread but the client still waits for it to finish.
I've done several searches and haven't found any method for the server process to disconnect the client.

HTTP response following long process

The current project is in Node.js with the Expressjs framework. We have an application with client/prospect information, authenticated users are allowed to modify the database and initiate long-running processes on the server. As an example, printing a 30 pg document could be one process.
The application user needs two main things:
A response when the process begins.
A response (notification) when the process ends.
We currently handle need #1 in standard express fashion by ensuring the process starts followed by res.json({msg: 'Process Started']); back to the Angular front end. Need #2 is currently handed with an email to the user that initiated the process with a process status report.
I would like to improve how we handle need #2. Specifically, I would like to send a JSON string to the user to display in the interface.
Questions:
Is it possible to do this over HTTP?
Does this functionality exist within Express or a well-know middleware.
Assuming 1 & 2 are false. My solution is to run a TCP socket server to maintain a socket with the required users. When a process ends a message is sent to the user with a status update. Can anyone comment on the issues my solution presents?
Yes to both 1 and 2. Essentially what you seek to achieve here is to push from the server to the client. The need to do this is pretty ubiquitous in web applications and there have been various solutions for it over the years with various fancy names. You might like to read up on Ajax, Comet, Long-polling, Websockets.
For your node application, take a look at socket.io. In a nutshell, what this framework does is it abstracts the complexities of Ajax, Websockets, etc. into a single API. Put another way, socket.io gives you bi-directional communications between your node application and front end.

Mobile to Web Service Communication

I created a web service and a mobile application that communicate between each other. When everything is working, it works great. When the server doesn't respond, it starts to break down.
The mobile device sends a message to the server with a bunch of records. Getting the records on the server never seems to be a problem. It gets the records and then sends a response back to the mobile device that the update was received. The PROBLEM is that the mobile device doesn't always get the response, so it doesn't know it shouldn't send those records again for updating.
Next time it sends the records again and now I have duplicate records. How can I solve this?
Idea 1) Create a transaction number unique on the mobile device that I can compare against the server to see if the record was already uploaded. Then just don't write that record and attempt to send back the response that it was written.
Idea 2) Send the records to the server, but before writing them respond to the mobile device that they were received. This way the mobile device can tag them and then send another response to the server telling it to write them. At the point the mobile device almost doesn't care if it gets a response. Only thing, you don't know if the server ever got the message.
Looking for ideas on how to handle this that either confirm one of these ideas or has a completely different one.
I ended up creating logs that the device attempts to resolve when it gets back successful responses from the server.
I tag items as a batch of lines and send them up to the server. Once they are up there, I create a log about the success or failure of each line item in a batch of items and then save the log to the file system.
When the mobile device is unsuccessful in hearing back a response from the server, in rare cases, it asks the server about a batch number. If the server doesn't respond with a status of that batch, it assumes the server never received it and remarks those items for another upload attempt. If it hears back, it processes the success and failure line by line and then marks the items on the mobile device accordingly. If the mobile device doesn't ask about the log in the next upload, the server assumes the batch's lifecycle is complete and it no longer needs to maintain that log. It is then deleted.
The server doesn't delete a log until it has a successful request from the specific device no longer asking to hear about the log. So if I have log 1 on the server and the device doesn't ask in the next upload to hear back about that log, the server then removes that log assuming the device got the response it wanted or doesn't care about it anymore.

Designing an interactive client

I'm trying to design a client program that connects to a remote server and sends various messages / request to it and expects responses based on the requests sent (for e.g. send a join message and wait for a response, then either query for some resource or ask for some info etc. in no particular order).
I would like to design the client such that the user can choose any of the possible requests to send after joining the server (after completing one request and getting a response if any it should allow them to carry out further requests or quit). Something like a menu of actions that it returns to each time (while also waiting for any data from the server)? However I can't seem to figure out how to this could be done. Is there a way to do this (preferably without getting into forking/threads)?
Any inputs on this would be really great. TIA
I would start off with a simple chat server to get your feel for socket programming. Google Example TCP Chat Server or something, you'll end up with simple examples like this: http://www.cs.ucsb.edu/~almeroth/classes/W01.176B/hw2/examples/tcp-server.c .. once you are able to telnet to your server and read/write to your clients, you should be able to progress from there and perform actions when your clients issue a specific command and that sort of thing.

How to achieve interrupt-driven communication from server to client with servlets?

we wrote in C++ a screen sharing application based on sending screenshots.
It works by establishing a TCP connection btw the server and client, where the server forwards every new screenshot received for a user through the connection, and this is popped-up by the client.
Now, we are trying to host this on google app engine, and therefore need 'servlet'-ize and 'sandbox' the server code, so to implement this forwarding through HTTP requests.
I immagine the following:
1. Post request with the screenshot as multiple-data form (apache uploads ..).
But now the server needs to contact the specified client (who is logged in) to send it/forward the screenshot.
I'm not sure how to 'initiate' such connection from the servlet to the client. The client doesn't run any servlet environment (of course).
I know HTTP 1.1 mantains a TCP connection, but it seems gapps won't let me use it.
1 approaches that comes to mind is to send a CONTINUE 100 to every logged in user at login, and respond with the screenshot once it arrives. Upon receival the client makes another request, and so on.
an alternative (insipired from setting the refresh header for a browser) would be to have the app pool on a regular basis (every 5 secs).
You're not going to be able to do this effectively on GAE.
Problem 1: All output is buffered until your handler returns.
Problem 2: Quotas & Limits:
Some features impose limits unrelated
to quotas to protect the stability of
the system. For example, when an
application is called to serve a web
request, it must issue a response
within 30 seconds. If the application
takes too long, the process is
terminated and the server returns an
error code to the user. The request
timeout is dynamic, and may be
shortened if a request handler reaches
its timeout frequently to conserve
resources.
Comet support is on the product roadmap, but to me your app still seems like a poor fit for a GAE application.
Long Polling is the concept used for such asynchronous communications between server and client.
In Long Polling, servlet keeps a map of client and associated messages. Key of Map being client id and value being list of messages to be sent to the client. When a client opens a connection with server (sends request to a servlet), the servlet checks the Map if there are any messages to be sent to it. If found, it sends the messages to the client exits from the method. On receiving messages, the client opens a new connection to the server. If the servlet does not find any messages for given client, it waits till the Map gets updated with messages for given client.
This is a late reply, I'm aware, but I believe that Google have an answer for this requirement: the Channel API.

Resources