FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Creando Servicios con Harbour y xHarbour
Posts: 1816
Joined: Wed Oct 26, 2005 02:49 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 03:54 PM

Antonio gracias como siempre por todo

Esto ya lo podemos usar en xharbour? o solo es para harbour? no entendí bien el mensaje?, la traducción en google no es muy clara.

Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 670
Joined: Wed Oct 19, 2005 06:41 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 04:08 PM

buenos dias con todos magino que la funcion

TrabajoServicio() va a reempalzar a la entrada o main de nuestra aplicacion solo una pregunta esto funciona para los programas multihilo ?? como hbnetio o como hbhttpd ?

gracias por todo Masters !!

saludos

Wilson 'W' Gamboa A
Wilson.josenet@gmail.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 04:13 PM
leandro wrote:Antonio gracias como siempre por todo

Esto ya lo podemos usar en xharbour? o solo es para harbour? no entendí bien el mensaje?, la traducción en google no es muy clara.
Funciona correctamente con Harbour y xHarbour
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 04:15 PM
wilsongamboa wrote:buenos dias con todos magino que la funcion
TrabajoServicio() va a reempalzar a la entrada o main de nuestra aplicacion solo una pregunta esto funciona para los programas multihilo ?? como hbnetio o como hbhttpd ?
gracias por todo Masters !!
saludos
la gran limitación es que no se puede usar NADA de GUI. Ni siquiera ni un MsgInfo() ó MsgBeep()
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 670
Joined: Wed Oct 19, 2005 06:41 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 04:34 PM

gracias antonio por contestar

pero sirve para programas multihilos ? que no tengan salida a pantalla claro

saludos

Wilson 'W' Gamboa A
Wilson.josenet@gmail.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Wed Sep 18, 2024 04:43 PM

Wilson,

habria que probarlo pero supongo que si, que debe funcionar multihilo correctamente

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sat Oct 12, 2024 08:37 AM
Antonio Linares wrote:
buenos dias con todos magino que la funcion
TrabajoServicio() va a reempalzar a la entrada o main de nuestra aplicacion solo una pregunta esto funciona para los programas multihilo ?? como hbnetio o como hbhttpd ?
gracias por todo Masters !!
saludos
la gran limitación es que no se puede usar NADA de GUI. Ni siquiera ni un MsgInfo() ó MsgBeep()
Hola Antonio. Partiendo de tener un servicio realizado con FWH, con las ventajas que supone pero la limitación de no poder interactuar con él de primeras. Cuál sería la forma más correcta para comunicarse con el servicio mediante otro programa de FWH? me refiero a montar otro programa que sí ejecuta el usuario cuando abre sesión y desde dicho programa, poder interactuar con el servicio para lanzar acciones, ver su estado, etc... Se me ocurre utilizar sockets?

Gracias y salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sat Oct 12, 2024 10:17 AM

Victor,

Si, posiblemente usar sockets funcione. No lo he probado

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sat Oct 12, 2024 04:28 PM
Antonio Linares wrote:Victor,

Si, posiblemente usar sockets funcione. No lo he probado
Hola Antonio.
Montando un ejemplo funcional con sockets, me ha funcionado. La conexión la realizo con postman para hacer las pruebas iniciales, luego si soluciono lo que te comento, haré un cliente para las pruebas básicas de interacción con el servicio. El problema es cuando activo el multithread para que después de aceptar una conexión, se quede escuchando de nuevo. Esto lo hago con algunas utilidades que tengo montadas con sockets y mt y me funciona perfectamente, pero en este caso no me funciona, no sé si es porque hay que adaptar la función que has realizado para el servicio en C a multithread, ahí me pierdo.

Con el siguiente código:
Code (fw): Select all Collapse
// Once you build the EXE open a CMD window as Administrator, then:
// sc create servicio binPath=c:\fwh\samples\servicio.exe
// sc start servicio
// when you want to stop it: sc stop servicio
// when you want to remove it: sc delete servicio
// DON'T USE ANY GUI FROM IT !!!

#include "FiveWin.ch"
#include "hbsocket.ch"


function Main()
    
    Local nPuerto := 8500

    public hListen := Nil
    public log := "c:\servicio.log"

    fErase( log )
    hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + 'iniciando socketserver' )
    hListen := hb_socketOpen( HB_SOCKET_AF_INET, HB_SOCKET_PT_STREAM, HB_SOCKET_IPPROTO_TCP )
    hb_socketBind( hListen, { HB_SOCKET_AF_INET, '0.0.0.0', nPUerto } )
    hb_socketListen( hListen )
    hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + 'socketserver iniciado en puerto ' + Str(nPUerto) )

    Servicio()

return nil

Function Listen()

    Local hSocket := Nil

    hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + Time() +'Escuchando puerto' )

    hSocket := hb_socketAccept( hListen,, 1000  )

    if Empty( hSocket )

        if hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT

                // No se hace nada, simplemente a superado el tiempo de espera para recibir una petición de conexión

        Else

            hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + 'accept error ' + hb_ntos( hb_socketGetError() ) )

        endif

    Else

        hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + 'conexión aceptada' ) 
        hb_threadDetach( hb_threadStart( @ServeClient(), hSocket, Self ) )

    endif

Return ( Nil )

Function ServeClient()

    hb_MemoWrit( log, hb_MemoRead( log) + hb_Eol() + 'ejecutando thread del cliente' ) 

Return ( Nil )

#pragma BEGINDUMP

#include <windows.h>
#include <tchar.h>
#include <hbvm.h>

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService( void );

HB_FUNC( SERVICIO )
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = _T("Servicio");
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;

    StartServiceCtrlDispatcher(ServiceTable);
}

#pragma warn -8057

void ServiceMain(int argc, char** argv )
{
    ServiceStatus.dwServiceType        = SERVICE_WIN32;
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint         = 0;
    ServiceStatus.dwWaitHint           = 0;

    hStatus = RegisterServiceCtrlHandler(_T("Servicio"), (LPHANDLER_FUNCTION)ControlHandler);

    if (InitService() == 0)
    {
        ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        SetServiceStatus(hStatus, &ServiceStatus);

        // Aquí va el bucle principal del servicio
        while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
        {
            // Realiza las tareas del servicio
            hb_vmPushSymbol( hb_dynsymSymbol( hb_dynsymFindName( "LISTEN" ) ) );
            hb_vmPushNil();
            hb_vmDo( 0 );

            // Sleep(1000); ya lo hago en el hb_socketaccept
        }
    }

    ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    SetServiceStatus(hStatus, &ServiceStatus);
}

void ControlHandler(DWORD request)
{
    switch(request)
    {
        case SERVICE_CONTROL_STOP:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ServiceStatus);
            MessageBox( 0, "service stopped", "ok", 0 );
            return;
        case SERVICE_CONTROL_SHUTDOWN:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ServiceStatus);
            return;
        default:
            break;
    }
    SetServiceStatus(hStatus, &ServiceStatus);
}

int InitService()
{
    // Inicialización del servicio
    return 0;
}

#pragma ENDDUMP
El resultado siguiente es compilado con buildh.bat, funciona correctamente pero al recibir la conexión se para la escucha:


En cambio si lo compilo con buildhmt.bat, no llega a ejecutar la función Listen(), se queda ahí:


puede ser algo de la función del servicio?

Gracias!!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sat Oct 12, 2024 04:32 PM
Algunas cosas que me he encontrado jugando con los servicios por si alguien llega por aquí y le pueden ser útiles:
sc config servicio5 start= auto configura el servicio para que se ejecute automáticamente al iniciar windows.

A veces te vuelve loco el tema del servicio, puede que lo tengas parado pero cuando compilas te indica el compilador que se está ejecutando el programa y a veces te deja compilar con el servicio en marcha y el servicio te ejecuta el último exe que has compilado automáticamente. Supongo que es porque los servicios de windows van con algún delay interno

Cuando se borra un servicio, en ocasioners no lo hace inmediato, a veces hay que reiniciar

El binPath ha de ser con la ruta completa, de lo contrario lo crea pero luego cuando lo inicias no encuentra el .exe

Salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sat Oct 12, 2024 07:35 PM

Victor,

Lo suyo sería construirlo solo con Harbour y no usar FWH porque si hay un error el GUI intentará mostrarse y ahi quedará bloqueado

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Sun Oct 13, 2024 04:39 PM
Un ejemplo sacado de hbwin/tests
Code (fw): Select all Collapse
#define _SERVICE_NAME "Harbour_Test_Service"

PROCEDURE Main( cMode )

   LOCAL nError
   LOCAL cMsg

   hb_default( @cMode, "S" ) /* NOTE: Must be the default action */

   SWITCH Upper( cMode )
   CASE "I"

      IF win_serviceInstall( _SERVICE_NAME, "Harbour Windows Test Service" )
         ? "Service has been successfully installed"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Error installing service: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   CASE "U"

      IF win_serviceDelete( _SERVICE_NAME )
         ? "Service has been deleted"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Error deleting service: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   CASE "S"

      /* NOTE: Used when starting up as service.
               Do not invoke the executable manually with this option */

      IF win_serviceStart( _SERVICE_NAME, @SrvMain() )
         ? "Service has started OK"
      ELSE
         nError := wapi_GetLastError()
         cMsg := Space( 128 )
         wapi_FormatMessage( ,,,, @cMsg )
         ? "Service has had some problems: " + hb_ntos( nError ) + " " + cMsg
      ENDIF
      EXIT

   ENDSWITCH

   RETURN

#include "fileio.ch"

PROCEDURE SrvMain( cParam1, cParam2 )

   LOCAL n := 0
   LOCAL fhnd := hb_FCreate( hb_FNameExtSet( hb_ProgName(), ".out" ), FC_NORMAL, FO_DENYNONE + FO_WRITE )
   LOCAL cParam

   hb_default( @cParam1, "" )
   hb_default( @cParam2, "" )

   FWrite( fhnd, "Startup" + hb_eol() )
   FWrite( fhnd, "|" + hb_CmdLine() + "|" + hb_eol() )
   FWrite( fhnd, "|" + cParam1 + "|" + cParam2 + "|" + hb_eol() )

   FOR EACH cParam IN hb_AParams()
      FWrite( fhnd, "Parameter " + hb_ntos( cParam:__enumIndex() ) + " >" + cParam + "<" + hb_eol() )
   NEXT

   DO WHILE win_serviceGetStatus() == WIN_SERVICE_RUNNING
      FWrite( fhnd, "Work in progress " + hb_ntos( ++n ) + hb_eol() )
      hb_idleSleep( 0.5 )
   ENDDO

   FWrite( fhnd, "Exiting..." + hb_eol() )
   FClose( fhnd )

   win_serviceSetExitCode( 0 )
   win_serviceStop()

   RETURN
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Mon Oct 14, 2024 05:56 PM
partiendo del repositorio :
Code (fw): Select all Collapse
https://github.com/FiveTechSoft/wsserver
y aplicado como servicio, pongo un pequeño ejemplo funcional:
es un servicio que incluye un servidor de sockets con multithread para procesar multiples conexiones simultáneas que permiten interactuar con el servicio.
Code (fw): Select all Collapse
//TODO: Definir el path del hb_out.log

#include 'hbwin.ch'
#include "hbsocket.ch"

#DEFINE SERVICE_NAME 'aaa'
#DEFINE HOST '0.0.0.0'
#DEFINE PUERTO 8500
#DEFINE LISTEN_TIMEOUT 1000
#DEFINE LOG 'c:\servicio_hb.log'
#define FILEHEADER "data:application/octet-stream;base64,"
#define JSONHEADER "data:application/json;base64,"
#define HTMLHEADER "data:text/html;base64,"

Function Main()

    fErase( LOG )
    win_serviceStart( SERVICE_NAME, @Servicio() )

Return ( Nil )

Function Servicio()

    Local hListen := Nil
    lOCAL hSocket := Nil

    hListen := hb_socketOpen( HB_SOCKET_AF_INET, HB_SOCKET_PT_STREAM, HB_SOCKET_IPPROTO_TCP )
    hb_socketBind( hListen, { HB_SOCKET_AF_INET, HOST, PUERTO } )
    hb_socketListen( hListen )

    if .Not. hb_mtvm()

        LogServer( 'Multithread no disponible. El servicio no se iniciará'  )
        win_serviceSetExitCode( 1 )
        win_serviceStop()
        Return ( Nil )

    Else

        LogServer( 'Multithread disponible'  )

    Endif


    LogServer( 'socketserver iniciado en puerto ' + Str(PUERTO) )

    While win_serviceGetStatus() == WIN_SERVICE_RUNNING

        LogServer( Time() +' Escuchando puerto' + Str( PUERTO ) )

        hSocket := hb_socketAccept( hListen,, LISTEN_TIMEOUT  )
    
        if Empty( hSocket )
    
            if hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT
    
                    // No se hace nada, simplemente a superado el tiempo de espera para recibir una petición de conexión
    
            Else
    
                LogServer( 'accept error ' + hb_ntos( hb_socketGetError() ) )
    
            endif
    
        Else
    
            LogServer( 'conexión aceptada' )
            hb_threadDetach( hb_threadStart( @ServeClient(), hSocket ) )
    
        endif

    Enddo

    win_serviceSetExitCode( 0 )
    win_serviceStop()

Return ( Nil )

Function ServeClient( hSocket )

    Local cBuffer := Space( 4096 )
    Local lConnectionClosed := .F.
    Local nLen := 0
    Local cRequest := ''
    Local nOpcode := 0

    hb_socketRecv( hSocket, @cBuffer,,, 1024 )
    HandShaking( RTrim( cBuffer ), hSocket )

    while .Not. lConnectionClosed

        LogServer( ThreadId() + ' Esperando petición de cliente' )

        cRequest := ''
        nLen := 1

        while nLen > 0

            cBuffer := Space( 4096 )

            if ( nLen := hb_socketRecv( hSocket, @cBuffer,,, LISTEN_TIMEOUT ) ) > 0  

                cRequest += Left( cBuffer, nLen )

            else

                if nLen == -1 .and. hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT

                    nLen = 0

                endif

            endif

        Enddo

        If !Empty( cRequest )

            cRequest:= UnMask( cRequest, @nOpcode )

            LogServer( ThreadId() + ' Respuesta:' + cRequest )

            switch cRequest

                case 'ACCION1'

                    LogServer( ThreadId() + ' Ejecutando la acción 1' )
                    hb_idleSleep( 1 )
                    LogServer( ThreadId() + ' Fin acción 1' )
                    
                exit

                case 'ACCION2'

                    LogServer( ThreadId() + ' Ejecutando la acción 2' )
                    hb_idleSleep( 1 )
                    LogServer( ThreadId() + ' Fin acción 2' )
                    
                exit

                case 'EXIT'

                    lConnectionClosed := .T.
                    LogServer( ThreadId() + ' Se solicita desconexión' )

                exit

                otherwise

                    LogServer( ThreadId() + ' Petición desconocida ' + cRequest )

                exit

            endswitch

        Else 

            //LogServer( 'Se ha recibido una petición vacia ' + cRequest )

        Endif

    Enddo

    LogServer( 'Desconectando Socket' )
    hb_socketShutdown( hSocket )
    LogServer( 'Cerrando Socket' )
    hb_socketClose( hSocket )

Return ( Nil )

Static Function HandShaking( cHeaders, hSocket )

    local aHeaders as Array := hb_ATokens( cHeaders, hb_Eol() )
    local hHeaders as Hash := {=>}
    Local cLine  as Character := ''
    local cAnswer as Character := ''
     
    for each cLine in aHeaders

        hHeaders[ SubStr( cLine, 1, At( ":", cLine ) - 1 ) ] = SubStr( cLine, At( ":", cLine ) + 2 )

    next
     
    cAnswer = "HTTP/1.1 101 Web Socket Protocol Handshake" + Hb_Eol() + ;
              "Upgrade: websocket" + Hb_Eol() + ;
              "Connection: Upgrade" + Hb_Eol() + ;
              "WebSocket-Origin: " + HOST + Hb_Eol() + ;
              "WebSocket-Location: ws://" + HOST + ":" + hb_ntos( PUERTO ) + Hb_Eol() + ;
              "Sec-WebSocket-Accept: " + ;
              hb_Base64Encode( hb_SHA1( hHeaders[ "Sec-WebSocket-Key" ] + ;
                               "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", .T. ) ) + Hb_Eol() + Hb_Eol()
    
    LogServer( 'Enviando HandShaking' )
    hb_socketSend( hSocket, cAnswer ) 
     
Return ( Nil )

Static function Unmask( cBytes, nOpcode )
   
    local lComplete := hb_bitTest( hb_bPeek( cBytes, 1 ), 7 )
    local nFrameLen := hb_bitAnd( hb_bPeek( cBytes, 2 ), 127 ) 
    local nLength, cMask, cData, cChar, cHeader := ""
 
    nOpcode := hb_bitAnd( hb_bPeek( cBytes, 1 ), 15 )
 
    do case
       case nFrameLen <= 125
          nLength = nFrameLen
          cMask = SubStr( cBytes, 3, 4 )
          cData = SubStr( cBytes, 7 )
 
       case nFrameLen = 126
          nLength = ( hb_bPeek( cBytes, 3 ) * 256 ) + hb_bPeek( cBytes, 4 )
          cMask   = SubStr( cBytes, 5, 4 )
          cData   = SubStr( cBytes, 9 )
 
       case nFrameLen = 127  
          nLength = NetworkBin2ULL( SubStr( cBytes, 3, 8 ) )  
          cMask   = SubStr( cBytes, 11, 4 )
          cData   = SubStr( cBytes, 15 )
    endcase 
 
    cBytes = ""

    for each cChar in cData
       cBytes += Chr( hb_bitXor( Asc( cChar ),;
                      hb_bPeek( cMask, ( ( cChar:__enumIndex() - 1 ) % 4 ) + 1 ) ) ) 
    next   
 
    do case
       case Left( cBytes, Len( FILEHEADER ) ) == FILEHEADER
          cBytes = hb_base64Decode( SubStr( cBytes, Len( FILEHEADER ) + 1 ) )
          cHeader = FILEHEADER 
 
       case Left( cBytes, Len( JSONHEADER ) ) == JSONHEADER
          cBytes = hb_base64Decode( SubStr( cBytes, Len( JSONHEADER ) + 1 ) )
          cHeader = JSONHEADER
 
       case Left( cBytes, Len( HTMLHEADER ) ) == HTMLHEADER
          cBytes = hb_base64Decode( SubStr( cBytes, Len( HTMLHEADER ) + 1 ) )
          cheader = HTMLHEADER
    endcase
    
 return cBytes 

  Static function NetworkBin2ULL( cBytes )

    local cByte, n := 0
    
    for each cByte in cBytes

       n += hb_BitShift( Asc( cByte ), 64 - cByte:__enumIndex() * 8 )

    next
    
 return n

 function NetworkULL2Bin( n )

    local nBytesLeft := 64
    local cBytes := ""
 
    while nBytesLeft > 0

       nBytesLeft -= 8
       cBytes += Chr( hb_BitAnd( hb_BitShift( n, -nBytesLeft ), 0xFF ) )

    end
 
 return cBytes
 
Static Function LogServer( cMessage )

    hb_MemoWrit( LOG, hb_MemoRead( LOG ) + hb_Eol() + cMessage )

Return ( Nil )

Static Function ThreadId()
Return ( '[' + hb_ntos( hb_threadId( hb_threadSelf( ) ) ) + ']......' )
Aquí una pequeña demo donde se ve el estado inicial del servicio, como se inicia, dos peticiones simultáneas por postman ( se pueden hacer mediante un cliente ce HB, javascript, o lo que uno quiera ) lo que se ejecuta dentro de cada petición lleva entre corchetes el thread correspondiente, y todo reflejado en un log, sin GUI para que no haya problemas de interrupciones del servicio por errores. Por supuesto, al ser un servicio ha de llevar un control de errores de cada acción que se hace, pero esto es solo una pequeña demo funcional que he montado por si a alguien le sirve.



Gracias Antonio por tu código y consejos y también al resto por ayudarme.

Salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 670
Joined: Wed Oct 19, 2005 06:41 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Mon Oct 14, 2024 07:59 PM

Felicitaciones Victor excelente tu trabajo

podrias poner un cliente con harbour para los que no tenemos mucha idea

que envie datos a ese server y recoja la respuesta

gracias

Wilson

Wilson 'W' Gamboa A
Wilson.josenet@gmail.com
Posts: 1816
Joined: Wed Oct 26, 2005 02:49 PM
Re: Creando Servicios con Harbour y xHarbour
Posted: Thu May 22, 2025 08:42 PM
Hola buenas tardes para todos...

de nuevo por aquí a molestarlos :D :D :D :oops:

Estamos tratando de implementar un servicio para el uso de nuestra aplicación, compilamos el ejemplo que viene en lo samples de fw, servicio.prg, funciona correctamente, pero nos surge la necesidad de pausar el servicio mientras se ejecuta una acción, para luego reiniciarlo al momento que termine de ejecutar dicha acción.

Por otro lado intentamos compilar el ejemplo que suministro nuestro colega Victor Casajuana, pero nos arroja el siguiente error:
┌────────────────────────────────────────────────────────────────────────────┐
?FiveWin for xHarbour 25.01 64bits - Jan. 2025   Harbour development power  │▄
?(c) FiveTech 1993-2025 for Microsoft Windows 9X/NT/200X/ME/XP/Vista/7/8/10 │█
└────────────────────────────────────────────────────────────────────────────┘?
  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀?
Compiling...
C:\xHar2501_64\bin\harbour servicio1 /n /d__64__ /i.\..\\include;C:\xHar2501_64\include /w /p
xHarbour 1.3.1 Intl. (SimpLex) (Build 20250219)
Copyright 1999-2024, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'servicio1.prg' and generating preprocessed output to 'servicio1.ppo'...
servicio1.prg(3) Error F0029  Can't open #include file: 'hbwin.ch'
* Compiling errors *

C:\fwh64_2501\samples>
Sera que no funciona con xharbour?

Gracias de antemano
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]