Cómo Depurar Servidores de Automatización Remota

 

Depurar un Servidor ActiveX es algo de las cosas más duras que existen: deberás primero testear el servidor localmente y después intentar depurarlo remotamente. Muchos servidores funcionarán de forma semejante en ambas situaciones.

A diferencia de los Servidores Locales que pueden tener el formato de EXE o DLL (in-proc), los servidores remotos deben ser EXEs. Una de las ventajas de los EXE es que tienen su propio conjunto de eventos pero una de las desventajas, en una situación remota, es que el servidor no tendrá ningún contenido visual y por tanto su depuración es verdaderamente dura.

. La forma como se debería crear y depurar un Servidor Remoto es como sigue:

1. Crea tu propio servidor como una clase de VFP.

Supongamos que tienes un proyecto llamado Books que tiene una clase tipo custom llamada taxes que calcula la tasa sobre ventas de las diversas provincias o estados para poder luego escribirlo en tu libro de contabilidad. La Clase podría estar estructurada de la siguiente forma:

* TaxLib.PRG

DEFINE CLASS taxes AS custom

PROCEDURE gettaxes

LPARAMETER cState

DO CASE

   CASE m.cState = "CA"

        RETURN .08

   CASE m.cState = "WA"

        RETURN .07

   CASE m.cState = "NY"

        RETURN .10

   OTHERWISE

        RETURN 0

ENDCASE

ENDPROC

ENDCLASS

 

Tu aplicación puede testear esta Clase dentro de VFP con un código similar al siguiente:

 

cState = "CA"

nBookPrice = 19.95

* Se podría usar SET CLASS

SET PROCEDURE TO TaxLib

oTaxes = CreateObject("Taxes")

nBookTax = oTaxes.GetTaxes(m.cState)

* m.nBookPrice

? "Book total:;

"+ALLTRIM(STR(m.nBookPrice+m.nBookTax))

 

La ventaja de este sistema es que estás trabajando con el entorno de desarrollo de VFP y puedes sacar partido del debugger para los errores más comunes como "Syntax Error", etc.

2. Cambia tu definición de clase a OLEPUBLIC y pruebalo localmente.

Teoricamente, ya hemos depurado muchos de los errores más comunes que los desarrolladores suelen tener. Ahora lo que queremos hacer es testear la clase como un Servidor ActiveX. Para poder hacer esto, actualizamos la definición de la clase para hacerla del tipo OLE Public y hacemos un rebuild del proyecto seleccionando la opción Build EXE. El siguiente ejemplo muestra esto con una clase definida en un PRG.

Cambia:

DEFINE CLASS taxes AS custom

a:

DEFINE CLASS taxes AS custom OLEPUBLIC

Nota: si estás usando una clase visual creada en un VCX, podrías ir a la ventana de diálogo de la Información de la clase y marcar la opción de OLE Public.

Una vez que hayas creado tu Servidor de Automatización ActiveX, puedes actualizar tu código de prueba de la forma que sigue (fíjate que no necsitamos en adelante usar SET CLASSLIB o SET PROC ya que la clase es automáticamente registrada en el Registry como una Clase ActiveX):

cState = "CA"

nBookPrice = 19.95

oTaxes = CreateObject("Books.Taxes")

nBookTax = oTaxes.GetTaxes(m.cState) * m.nBookPrice

? "Book total: ";

+ALLTRIM(STR(m.nBookPrice+m.nBookTax))

Si has ejecutado correctamente el punto 1 no deberías encontrar muchos bugs, sin embargo, hay unas pocas cosas que se deben tener en cuenta. Ya que el Servidor ActiveX usa el runtime y no soporta todo el lenguaje de FoxPro (especialmente algunos de los elementos que hacen referenica al interfaz). Asegúrate de que no usas órdenes que no funcionan con el runtime.

3. Depuración remota del Servidor ActiveX.

Ya debes de haber creado tu Servidor ActiveX. Ahora, necesitamos registrarlo remotamente. La forma más fácil para hacer esto es usar el

Remote Automation Connection Manager (RacMan). RacMan te permite usar un ActiveX Server que haya sido creado localmente para pasar a registrarlo remotamente. Para poder hacer esto, asegúrate de que tu máquina remota tiene ese servicio instalado y registrado de la forma correcta con los derechos de paso correctamente configurados para el cliente. Finalmente, para crear una instancia de ese servidor, deberías estar corriendo DCOM (Distributed COM o Network OLE) entre tus máquinas (NT 4.0 o posteriores), o que está corriendo el programa Automation Manager que viene con VFP en el Servidor. Mira la documentación de VFP para tener más detalles sobre esto.

Muchos de los problemas que suele haber con el uso de servidores de automatización remota no se suelen plantear con los propios servidores sino más bien a la hora de configurarlos correctamente con las direcciones correctas, protocolos, derechos de acceso, etc...

El problema más común que se suele presentar son las órdenes de espera que podrían parar al cliente como un MessageBox() que nos mostraría una ventana de diálogo en el Servidor que mientras no sea cerrada en el Servidor impedirá que se avance en el cliente.

 

Estarategia de control de Errores

El control de Errores suele ser uno de los problemas más comunes de los Servidores Remotos. Es imperativo que tu control de errores evite usar diálogos que puedan poner tu servidor en un estado modal. El control de errores debería enviar un error (posiblemente un mensage) al cliente para que sea propiamente controlado.

Dependiendo de lo conservador que seas con tu código, podrías comprobar después de cada llamada al servidor llamando a una rutina de error que te permita controlar esos errores.

Evita los estados de espera. En general, tus servidores remotos no serán visuales. Puede haber muchos extraños controles de espera tales como

BROWSE, MODIFY MEMO, WAIT WINDOW, etc. Que esperan que el usuario haga algo. Intenta evitar este tipo de código que te podrían provocar la entrada en un loop sin fin.

Usa propiedades de la Clase aplicación. Hay bastantes propiedades que puedes usar en tus aplicaciones cliente para controlar de una forma más efectiva los problemas que se presentan con los Servidores ActiveX. Estos incluyen:

OLEServerBusyTimeout

OLERequestPendingTimeout

OLEServerBusyRaiseError

StartMode

Ten cuidado con los problemas de bloqueo. Visual FoxPro soporta la capacidad de hacer Callbacks a los clientes. Una referencia a un objeto en el cliente se puede pasar a un servidor remoto. El Servidor Remoto puede establecer ejecutar un método o establecer una propiedad de este objeto. Cuando esto sucede en una situación remota, el Automation Manager se lanza de forma automática en la máquina cliente. Un problema frecuente con estas Callbacks es que el cliente pase la referencia de un objeto a un método en el servidor. Este método trata entonces de hacer una callback sobre ese objeto. Un problema de bloqueo se produce (Error: La llamada ha sido rechazada) ya que el cliente está esperando a que el método complete su ejecución. A continuación hay un ejemplo que muestra esto.

* Código del Cliente

x=create("myproj.myserver")

y=create("form")

x.test(y)

** se genera un error debido al bloqueo

* Código del Servidor en el proyecto Myproj

DEFINE CLASS myserver AS custom OLEPUBLIC

   PROCEDURE test

   PARAMETER oForm

       oForm.Caption = "Hello World"

   ENDPROC

ENDDEFINE

 

  Errores más comunes con el Remote Automation

Error: OLE code code 0x800706d9: There are no more endpoints available from the endpoint mapper
Possible Causes: Automation Manager/DCOM not started (running) on server.
Remedy: If using Automation Manager, make sure to launch the program. With DCOM, check DCOM documentation for possible problems

configuring it. If a successful connection is made, the Automation Manager window will indicate so.

Error: OLE error code 0x800706a7: The RPC protocol sequence is not supported.
Possible Causes: The Network Protocol specified on the client machine for the remote server is not supported.

Remedy: On the client machine, launch the Remote Automation Connection Manager and go into the Server Connection tab. Select a Network

Protocol that is supported such as TCP/IP.

Error: OLE error code 0x80070005: Access is denied.
Possible Causes: This is often due to improper client access set on the server.
Remedy: On the server machine, launch the Remote Automation Connection Manager and choose the Client Access tab. Make sure the System

Security Policy is set correctly. If this does not work, try using one of the other Policy options such as Allow All Remote Creates.

Error: OLE error code 0x800706e4: The requested operation is not supported.
Possible Causes: This is often due to improper client access set on the server when the System Security Policy is set to Allow Remote Creates

by ACL.

Remedy: On the server machine, launch the Remote Automation Connection Manager and choose the Client Access tab. The 3rd option should

already be selected (Allow Remote Creates by ACL). Make sure The ACL (Access Control List) privileges are set correct to allow for client

access via the Edit ACL button. If this does not work, try using one of the other Policy options such as Allow All Remote Creates.

Error: OLE error code 0x80010001: Call was rejected by callee.
Possible Causes: Block in OLE Callback
Remedy: Make sure that callbacks are made independent of the client's actions. Use a timer as in the Pool Manager example.
Error: Server busy or mousepointer endlessly busy
Possible Causes: This is often due to some wait state in the server such as an error dialog, messagebox, browse, etc.
Remedy: Avoid using code which require user input.
Error: Feature not available.
Possible Causes: Command or function is not available in runtime version.
Remedy: Do not use these commands.

© 1998 FoxPress. All rights reserved.