PDA

Ver la Versión Completa : [Compilador] Powercobol búsqueda lenta ficheros indexados LAN


Joseg
9 de mayo de 2017, 00:03
Algunas rutinas de búsqueda en PowerCOBOL (busqueda incremental, indexed file), que están recibiendo muy lento cuando se ejecuta en un PC cliente que accede a una carpeta compartida en el servidor.
Me gustaría poder hacer esto procesamiento de búsqueda (u otra acción) en el servidor y volver a la PC cliente sólo el resultado. En Fujitsu Cobol existe el recurso Inter-application Communication Function" (cobol - sample29), pero no parece practico teniendo en cuenta que tengo que configurar los ajustes manualmente en todos los PCs. ¿Hay alguna alternativa (algo parcido con el cliente / servidor).

Gracias

Kuk
9 de mayo de 2017, 09:08
Joseg, puedes crear un "Listener" / "Daemon" y ejecutarlo en servidor. Luego se puede montar un mecanismo por ficheros temporales, o más limpio pero más complicado con MSWINSCK.OCX (socket).

Joseg
10 de mayo de 2017, 10:40
Joseg, puedes crear un "Listener" / "Daemon" y ejecutarlo en servidor. Luego se puede montar un mecanismo por ficheros temporales, o más limpio pero más complicado con MSWINSCK.OCX (socket).

No sé si puede ayudar. En el evento "DataArrival" (en el servidor), no recibe una cadena como fue enviada por el cliente.
He hecho varios cambios, pero sin éxito.

Gracias

Kuk
10 de mayo de 2017, 13:16
Joseg, parece ser problema de codificación de caracteres. He hecho pruebas, con los valores numéricos en campos binarios (COMP-5) todo funciona bien. El WinSock parece trabajar con strings de UNICODE. Creoq ue el problema viene de ahí. Seguiré investigando.

Joseg
10 de mayo de 2017, 16:17
Joseg, parece ser problema de codificación de caracteres. He hecho pruebas, con los valos numéricos en campos binarios (COMP-5) todo funciona bien. El WinSock parece trabajar con strings de UNICODE. Creoq ue el problema viene de ahí. Seguiré investigando.

"Retrieves the current block of data and stores it in a variable of type variant." - Microsoft

El problema esta en la definición de una variable tipo "variante" cosa que el Powercobol no soporta.
Si funcionara resolvía mi problema.

Tengo que buscar otra alternativa.

Dasije
10 de mayo de 2017, 17:09
Usa archivos secuenciales con directiva BSAM, es muy rápido.

La idea es utilizar estos archivos como si fueran "vistas", como tablas view en SQL Server, habría que estar actualizando sus datos desde sus ficheros de origen, no es necesario sacar todos los datos del archivo, solo con los datos que se vayan a mostrar en una tabla.

Hay que tener en cuenta que los controles de Windows, si tienen repintado de datos al tiempo que guardan líneas con datos, relantiza el proceso de generación de la consulta, hay que evitar este detalle, pero aún si, el control en concreto puede crear relantización por su programación.

No es lo mismo leer un archivo indexao a pelo desde una ventana consola de NetCOBOL que en el mismo PowerCOBOL, hay una gran diferencia, prueba de ello, los controles de Windows relantizan la lectura, y más aún si utilizan el método Thruevents para evitar que la ventana se quede congelada.

Salduos.

Kuk
10 de mayo de 2017, 21:24
Joseg, ¡¡¡lo he conseguido!!! :fuma:

Nitzer
10 de mayo de 2017, 21:57
Me dejais anonadado, mañana le echare un vistazo. Cuanto queda por aprender, me da miedo

Kuk
11 de mayo de 2017, 09:28
Nitzer, ¡viva el REDEFINES! :D En realidad lo que hice fue redefinir el string en un array de Integers:

Entonces en el cliente hago:

ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 wsmsg pic x(24).
01 FILLER REDEFINES wsmsg.
05 wsINT OCCURS 6 TIMES PIC S9(9) COMP-5.
01 IDX-1 PIC S9(4) COMP-5.
PROCEDURE DIVISION.

move "Text" OF CmText1 to wsmsg

IF "State" OF Winsock1 = 7
MOVE 1 TO IDX-1

PERFORM UNTIL IDX-1 > 6
INVOKE Winsock1 "SendData" USING wsINT(IDX-1)

ADD 1 TO IDX-1
END-PERFORM
END-IF


Y en el servidor:


ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 wsmsg pic x(24).
01 FILLER REDEFINES wsmsg.
05 wsINT OCCURS 6 TIMES PIC S9(9) COMP-5.
01 IDX-1 PIC S9(4) COMP-5.
LINKAGE SECTION.
01 POW-ARG-BYTESTOTAL PIC S9(9) COMP-5.
PROCEDURE DIVISION USING POW-ARG-BYTESTOTAL.

MOVE 1 TO IDX-1

PERFORM UNTIL IDX-1 > 6
INVOKE Winsock1 "GetData" USING wsINT(IDX-1) 3

ADD 1 TO IDX-1
END-PERFORM

MOVE wsmsg TO "Caption" OF CmStatic9


Joseg, según he visto, todos los tipos derivan del Variant:


Public Const vbArray As Microsoft.VisualBasic.VariantType = 8192
Public Const vbBoolean As Microsoft.VisualBasic.VariantType = 11
Public Const vbByte As Microsoft.VisualBasic.VariantType = 17
Public Const vbDate As Microsoft.VisualBasic.VariantType = 7
Public Const vbDecimal As Microsoft.VisualBasic.VariantType = 14
Public Const vbLong As Microsoft.VisualBasic.VariantType = 20
Public Const vbString As Microsoft.VisualBasic.VariantType = 8
Public Const vbLong As Microsoft.VisualBasic.VariantType = 20
Public Const vbInteger As Microsoft.VisualBasic.VariantType = 3
Public Const vbSingle As Microsoft.VisualBasic.VariantType = 4


Seguro que el "String" tiene su TypeDef que se compone por campos nativos, pero no he encontrado la información necesaria, así que pensé en el REDEFINES.

Joseg
11 de mayo de 2017, 10:28
¡Fantastico !!! Con esta técnica tal vez pueda resolver otros problemas que he tenido con otros OCX.

Kuk
11 de mayo de 2017, 21:37
Joseg, si haces pruebas con otros OCX publícalas en el foro ;)

Nitzer
12 de mayo de 2017, 18:30
Vamos a ver, en primer lugar:

ME HABEIS HECHO PERDER EL DIA CON EL .... SOCKET JJJJJJJJJ

Pero tengo el honor de presentaros el Cobosap (una mezcla de Cobol con Guasap), ahí queda eso.

Un resumen:
- He incluido tanto el cliente como el servidor en el mismo ejecutable, de hecho son el mismo ejecutable.
- Tiene que existir un .ini (en el ejemplo va uno para que veais como construirlo.
- Para ejecutar el sistema Servidor, al ejecutarlo añadir una S al commandline, es decir: COBOSAP S
- Para el cliente no incluir nada, solo ejecutar.

He aprovechado también para que veáis como hago mis ventanas movibles sin usar el sistema de Windows, seguro que sabéis como hacerlo, pero igual a alguien le puede venir bien. Además con efecto "imán" cuando está cerca de un borde. :)

EL sistema detecta si hay comunicación en cualquier dirección y habilita o deshabilita el botón de enviar si no hay conexión tanto de una parte como de otra.

Bueno, pues eso, estáis tardando en probarlo.

Kuk
13 de mayo de 2017, 11:05
Nitzer, se te ha olvidado incluir el icono ;)

También hay que eliminar el valor de TargetFolderRelease de las propiedades de COBOSAP [Module], que contiene "U:\SOCKET"

Buen ejemplo del uso del Socket amigo Andrés, si señor. Habría que mirar cómo se hace para que sea multicliente y conexión entre varios simultáneamente.

Nitzer
13 de mayo de 2017, 11:33
Es verdad Kuk, se me olvidó quitarlo jjjjj. El icono es que tampoco me iba, no se porque y no quise perder mas tiempo, que cada uno le ponga el que quiera.

Lo del multi..... lo dejo para otro. :)
Recordad que para mover la pantalla, es arrastrando la barra negra superior.

Dasije
13 de mayo de 2017, 17:43
Lo de multiconexion es fácil, crear tanto controles socket se necesita y en cada conexión generarle un identificador, e ir comprobando lo que se va recibiendo y asignando al socket al que debe escuchar.

Lástima que PowerCOBOL no pueda clonar objetos en tiempo de ejecución, que sería su verdadero objetivo en este caso, en Windev si se puede hacer.

Kuk
13 de mayo de 2017, 20:41
Dasije, deja de hacer publicidad al Windev hombre :D Que vamos a pensar que tienes acciones y todo :D ;)

En cuanto al tema, yo creo que la utilización del Socket sobre todo sería útil en propósitos como el de Joseg. Y en cuanto a clonarlo, yo creo que estás equivocado. Todo OCX tiene su Prog-ID, y con el Prog-ID podemos hacerlo:


ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 COM-OBJECT OBJECT REFERENCE COM.
01 ProgID PIC X(50) VALUE "MSWinsock.Winsock".
PROCEDURE DIVISION.

INVOKE COM "CREATE-OBJECT" USING ProgID RETURNING COM-OBJECT

Dasije
14 de mayo de 2017, 17:29
No es por publicidad comercial, puedo decir que en Delphi también se puede hacer con la sentencia Create, en Windev sería ControlClone.

Control2 = Control1.Create()

En PowerCOBOL, no he visto nada en relación a ello, lo más parecido a ello son array previamente creado antes, habría que mirar la api de windows, que funciones intervienen en cada paso para clonar.

Sobre PROG-ID, es un número único que asigna el sistema operativo a cada objeto o activex que entra en acción con el sistema, lo correcto sería el handle del objeto que genera cada vez que se ejecuta.

Kuk
14 de mayo de 2017, 20:51
No es por publicidad comercial, puedo decir que en Delphi también se puede hacer
Ya, pero me refiero a que en este tema estamos hablando de PowerCOBOL. Está claro que se puede hacer en otros entornos ;)


Sobre PROG-ID, es un número único que asigna el sistema operativo a cada objeto o activex que entra en acción con el sistema

No, esto de lo que estás hablando es el CLASS-ID, el PROG-ID es lo que he dicho antes. Mira el pantallazo que adjunto.
El ejemplo que puse antes del CREATE-OBJECT con el Winsock funciona, no es "pseudo código". Además, aquí tienes otro ejemplo de creación dinámica de un objeto: [Aporte] Uso del ChartControl de Codejock - COBOL Foro (http://cobolforo.es/showthread.php?t=140)


MOVE "Codejock.ChartAreaSeriesStyle.15.0.1" TO TXT
INVOKE COM "CREATE-OBJECT" USING TXT RETURNING CHART-STYLE


El Handle, no siempre es expuesto (no es declarado como público), además sólo existe después de instanciar la clase.

Y por cierto, simepre nos queda crear un módulo en OO COBOL e instanciar esa clase definida.

Rapinto
16 de mayo de 2017, 00:17
KUK,

Sabes como resolver, utilizando *COM, os eventos do objecto COM??
Por exemplo neste caso o evento do "Winsock.ocx" "DataArrival"?

Nunca consegui utilizar Events. Apenas Properties and Methods.
Nem sei se é possível.
Un saludo,
Rui Pinto

Kuk
16 de mayo de 2017, 10:16
Rapinto, nunca lo he intentado. Se me ocurre que a lo mejor con el subclassing del Form se podría conseguir. Es decir, en el bucle, el


BOOL WINAPI GetMessage(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax
);


Debería también recibir notificaciones de eventos de los objetos creados dinamicamente. Y con el subclassing se podrá interceptarlos. Aunque es la teoría, no estoy seguro de ello.

Joseg
19 de mayo de 2017, 18:06
Lo de multiconexion es fácil, crear tanto controles socket se necesita y en cada conexión generarle un identificador, e ir comprobando lo que se va recibiendo y asignando al socket al que debe escuchar.

Lástima que PowerCOBOL no pueda clonar objetos en tiempo de ejecución, que sería su verdadero objetivo en este caso, en Windev si se puede hacer.


Activado la opción "array" no es suficiente?
Ejemplo: INVOKE Winsock1(ind) "Connect"
...

Dasije
19 de junio de 2017, 13:59
Sí puede perfectamente servirte, tendrías que ver cuantos usuarios van a conectarse para crear x arrays.

Saludos.