Web Connection
Switching fto Web Connect from AVFP
Gravatar is a globally recognized avatar based on your email address. Switching fto Web Connect from AVFP
  Scott R
  All
  Apr 11, 2018 @ 01:39pm

Rick,

We’ve used web connect in the past but it’s been a while since we’ve done anything new with it. We are currently running / using it but it’s been years since we’ve updated any code. We are currently using AVFP for restful web services for our mobile app and are looking into switching all of that over to web connect.

That being said, we have a few questions for you.

  1. How do we pull things out of the body? In the past we pulled parameters out of the query string so we’re familiar with that but how do you pull parameters out of the body?
  2. Currently, with web connect, we have to manually sign in to windows in order for it to launch after a computer restart. It does start automatically once we sign in but it won’t start until we sign in. Is there any way to have web connect start automatically like IIS does so we don’t have to sign in to launch it? (AVFP is basically a ‘web site’ in IIS so when IIS starts it’s up and running and IIS starts with windows)
  3. In relation the question 2, does webconnect run through IIS or something else entirely?
  4. This is slightly off topic as far as switching over to webconnect, but related to our web services and didn’t know if you had any ideas. In our webservice, we connect to our client’s sql server database. We’ve had problems where if their server is having problems (i.e. offline / restarting or some other reason we can’t connect), IIS get’s ‘hung’ if you will and all requests stop processing until we restart IIS, in which case we are then back up and running but we get ‘hung’ again as soon as the client tries to do something else on our mobile app. As we process the request and try to connect to their server we in essence go down as we get stuck trying to connect to them. Is there a way to prevent this (i.e. a max time on a worker process or maybe you have some timeout setting in WebConnect separate from worker processes in IIS?) Have you heard of this happening before?

Thanks for your help.

Gravatar is a globally recognized avatar based on your email address. re: Switching fto Web Connect from AVFP
  Rick Strahl
  Scott R
  Apr 11, 2018 @ 01:56pm

How do we pull things out of the body? In the past we pulled parameters out of the query string so we’re familiar with that but how do you pull parameters out of the body?

Use Request.Form().

Currently, with web connect, we have to manually sign in to windows in order for it to launch after a computer restart. It does start automatically once we sign in but it won’t start until we sign in. Is there any way to have web connect start automatically like IIS does so we don’t have to sign in to launch it? (AVFP is basically a ‘web site’ in IIS so when IIS starts it’s up and running and IIS starts with windows)

Yes - if you run under COM, servers will automatically be started when the server starts. You can also auto-start file servers using configuration AutoStartServers and ServerCount configuration settings. These are the settings that control launching:

AutoStartServers only applies when running in File mode. COM servers always auto-start.

In relation the question 2, does webconnect run through IIS or something else entirely?

Web Connection runs as an ASP.NET handler or as an ISAPI Handler (not recommended any longer) or as Apache Module. But in most cases - yes - it runs through IIS or IIS Express typically.

IIS get’s ‘hung’ if you will and all requests stop processing until we restart IIS, in which case we are then back up and running but we get ‘hung’ again as soon as the client tries to do something else on our mobile app. As we process the request and try to connect to their server we in essence go down as we get stuck trying to connect to them. Is there a way to prevent this (i.e. a max time on a worker process or maybe you have some timeout setting in WebConnect separate from worker processes in IIS?)

This is due to FoxPro's single threaded nature - if you somehow manage to 'hang' a FoxPro instance, that instance is hung and stays hung. Web Connection runs multiple instances simultaneously, so you'd need to hang all instances. Web Connection will kill any hung instances (instances that haven't returned) when their request timeout is up and start new instances.

However if you have a problem with your SQL backend hanging and it's permanently hanging it'll always tie up all instances and you get that frozen affect as all instances evenutally get blocked. There's really nothing you can do about that short of fixing the SQL issue so I'm not surprised that this happens with AVFP as well. Except AVFP will have likely an uncontrolled number of instances spin up possibly freezing the entire server - Web Connection has a specific pool of instances you specify allocated so you control how much simultaneous processing can occur (CPU bound). Worst case you can restart the Site/Virtual that host your application. It won't bring down Windows.

Hanging your app in a Web app is always a problem because in a busy site this always spirals out of control very quickly. To counteract that make sure your SQL connect timeouts are short (not the 15 second default, 2 or 3 seconds should be plenty if the server is on local network) so a connection failure doesn't tie up the server for a long time.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Switching fto Web Connect from AVFP
  Scott R
  Rick Strahl
  Apr 24, 2018 @ 08:29am

Rick,

Thanks for the reply. I'm in the process of testing our login using web connect instead of AVFP. In avfp, we manually formatted the response string for JSON. However, now when web connect returns it I'm getting extra escape characters.

i.e. (Response as displayed in browser debug tools -> Network -> Response)

AVFP String Response:

{"errorCode":"-3","errorDesc":"User Name not found."}

Web Connect String Response:

"{\"errorCode\":\"-3\",\"errorDesc\":\"User Name not found.\"}"

In my code I'm doing:

RETURN '{"errorCode":"-3","errorDesc":"User Name not found."}'

Yes, I know this is the hard way but it worked well for the way that AVFP worked as it returned exactly what you said. We either return a cursor as a JSON string / object or the above type of error message string and so I'm leary to go through and refactor all of my code to make it an object with the 'errorCode' and 'errorDesc' properties simple due to the shear number of procs I'd have to update (it's well over a hundred). If that's what has to be done, we'll make it work but we'd rather not...

How do I make it return EXACTLY like my return statement and NOT have webconnect reformat in any way? I've tried the JsonService.IsRawResponse = .T. but all I get is an empty string when I set that to .T.

Thanks,

Scott

Gravatar is a globally recognized avatar based on your email address. re: Switching fto Web Connect from AVFP
  Rick Strahl
  Scott R
  Apr 24, 2018 @ 01:17pm

Scott,

When you're using a REST service Web Connection returns results as proper JSON, which means if you return a string (as you are) it'll return a JSON string which is why you're seeing the quotes around the JSON object you are trying to return.

The are a couple of ways to fix this.

#1 - Use Raw Output

You can specify that you want to generate raw output

FUNCTION RawResult()

*** We take over the Response here - no JSON Serialization
JsonService.IsRawResponse = .T.

* Response.ContentType = "text/html"   && Default is application/json
Response.Write('{"errorCode":"-3","errorDesc":"User Name not found."}')
Response.End()
ENDFUNC

More info here:

#2 - Create a proper Object

Probably a better approach since you DO want to actually return a JSON object is to create an object and return it instead of a string:

FUNCTION ErrorResult()
LOCAL loErr

loErr = CREATEOBJECT("BLANK")
ADDPROPERTY(loErr,"errorCode","-3")
ADDPROPERTY(loErr,"errorDesc", "User Name not found")


*** Make sure serialization properly creates capitalization
Serializer.cPropertyNameOverrides = "errorCode,errorDesc" 

RETURN loErr
ENDFUNC

The latter is generally the better approach. In fact for errors and common message response I tend to create helper methods that create these generic reusable responses for me:

*** Main line code
FUNCTION DoSomething

if (!loBus.IsValid())
   RETURN THIS.ReturnError("-3","Validation failed: " + loBus.cErrorMsg)
ENDIF

RETURN loBus.oData
ENDFUNC


*** Helper to return an error response
FUNCTION ReturnError(lcErrorCode, lcErrorMessage)

LOCAL loErr

loErr = CREATEOBJECT("BLANK")
ADDPROPERTY(loErr,"errorCode","-3")
ADDPROPERTY(loErr,"errorDesc", "User Name not found")

*** Make sure serialization properly creates capitalization
Serializer.cPropertyNameOverrides = "errorCode,errorDesc" 

RETURN loErr
ENDFUNC

Hope this helps,

+++ Rick ---

© 1996-2024