Spanish Problema en recepción de datos asíncrona [SOLUCIONADO]

carlos7000

Well-Known Member
Licensed User
Longtime User
Hola. Estoy tratando de crear una clase que incluye un par de subs para solicitar datos json a un servidor remoto. Las funciones colocadas en el Main funcionan bien. Pero al pasarlas al modulo class dejan de funcionar. y el programa falla. Estas son las dos funciones:

B4X:
private Sub SendCommand(work As String, uri As String)
    Try
        Dim nonce As Long
        nonce = DateTime.now

        uri = uri & "&nonce=" & nonce

        Dim sign() As Byte
        sign = HashHmac(uri, API_Secret)

        Dim API_Signed As String
        Dim Byte_Conv As ByteConverter
        API_Signed = Byte_Conv.HexFromBytes(sign) 'convert to HEX
        API_Signed = API_Signed.ToLowerCase

        Dim j As HttpJob

        j.Initialize(work, "money")
        j.PostString(uri, "")
        j.GetRequest.SetHeader("apisign", API_Signed)
    Catch
        Log(LastException)
    End Try
End Sub

private Sub jobDone (job As HttpJob)
    Try
        Log(job.Success)
        Log(job.GetString)

        If (job.JobName == "CmdGetTicker") Then
            Dim parser As JSONParser
            parser.Initialize(job.GetString)
            Dim root As Map = parser.NextObject
            Dim result As Map = root.Get("result")
            Dim Last As Double = result.Get("Last")
            LastOld = LastNow
            LastNow = Last
            Dim Ask As Double = result.Get("Ask")
            AskOld = AskNow
            AskNow = Ask
            Dim Bid As Double = result.Get("Bid")
            BidOld = BidNow
            BidNow = Bid
            Dim success As String = root.Get("success")
   
            status = success 'Save status
   
            Dim message As String = root.Get("message")
        End If

        'guardamos la hora de al recepcion de los datos
        TimeOld = DateTime.Now
    Catch
        Log(LastException)
    End Try
End Sub

Entonces escribí este otro código, que no me gusta porque detiene el programa a la espera de los datos. y tampoco funciona. Al llegar al Wait el programa falla catastróficamente y se cierra.

B4X:
private Sub SendCommand(work As String, uri As String)
    Try
        Dim nonce As Long
        nonce = DateTime.now

        uri = uri & "&nonce=" & nonce

        Dim sign() As Byte
        sign = HashHmac(uri, API_Secret)

        Dim API_Signed As String
        Dim Byte_Conv As ByteConverter
        API_Signed = Byte_Conv.HexFromBytes(sign) 'convert to HEX
        API_Signed = API_Signed.ToLowerCase

        Dim j As HttpJob

        j.Initialize(work, "money")
        j.PostString(uri, "")
        j.GetRequest.SetHeader("apisign", API_Signed)

        Wait For (j) jobDone(j As HttpJob)
   
        If j.Success  Then
            If (j.JobName == "CmdGetTicker") Then
                Dim parser As JSONParser
                parser.Initialize(j.GetString)
                Dim root As Map = parser.NextObject
                Dim result As Map = root.Get("result")
                Dim Last As Double = result.Get("Last")
                LastOld = LastNow
                LastNow = Last
                Dim Ask As Double = result.Get("Ask")
                AskOld = AskNow
                AskNow = Ask
                Dim Bid As Double = result.Get("Bid")
                BidOld = BidNow
                BidNow = Bid
                Dim success As String = root.Get("success")
   
                status = success 'Save Status
   
                Dim message As String = root.Get("message")
            End If
        End If
   
    Catch
        Log(LastException)
    End Try
End Sub

La clase completa, por ahora, es:

B4X:
Sub Class_Globals
    Dim name As String
    Private API_Key  As String
    Private API_Secret  As String

    Dim BidOld As Double
    Dim AskOld As Double
    Dim LastOld As Double
    Dim TimeOld As Long

    Dim BidNow As Double
    Dim AskNow As Double
    Dim LastNow As Double

    Dim status As String


End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(money As String, Key As String, Secret As String)
    name = money
    API_Key = Key
    API_Secret = Secret
End Sub

private Sub HashHmac(data As String, secret As String) As Byte()
    Try
        Dim m As Mac                                         'm As Message Authentication Code
        Dim kg As KeyGenerator                               'kg As KeyGenerator
        kg.Initialize("HmacSHA512")                          'initialize kg using HmacSHA512 algorithm
        kg.KeyFromBytes(secret.GetBytes("UTF8"))             'encode string "secret" to an array of Bytes using UTF8
        m.Initialise("HmacSHA512", kg.Key)                   'initialize m using HmacSHA512 algorithm and the secret key
        m.Update(data.GetBytes("UTF8"))                      'encodes post data to an array of Bytes and loads it to be signed
        Return m.Sign                                        'sign the loaded data using the secret key, return the calc signature data
    Catch
        Log(LastException)
    End Try
End Sub

private Sub SendCommand(work As String, uri As String)
    Try
        Dim nonce As Long
        nonce = DateTime.now

        uri = uri & "&nonce=" & nonce

        Dim sign() As Byte
        sign = HashHmac(uri, API_Secret)

        Dim API_Signed As String
        Dim Byte_Conv As ByteConverter
        API_Signed = Byte_Conv.HexFromBytes(sign) 'convert to HEX
        API_Signed = API_Signed.ToLowerCase

        Dim j As HttpJob

        j.Initialize(work, "money")
        j.PostString(uri, "")
        j.GetRequest.SetHeader("apisign", API_Signed)

        Wait For (j) jobDone(j As HttpJob)
   
        If j.Success  Then
            If (j.JobName == "CmdGetTicker") Then
                Dim parser As JSONParser
                parser.Initialize(j.GetString)
                Dim root As Map = parser.NextObject
                Dim result As Map = root.Get("result")
                Dim Last As Double = result.Get("Last")
                LastOld = LastNow
                LastNow = Last
                Dim Ask As Double = result.Get("Ask")
                AskOld = AskNow
                AskNow = Ask
                Dim Bid As Double = result.Get("Bid")
                BidOld = BidNow
                BidNow = Bid
                Dim success As String = root.Get("success")
   
                status = success 'Guardamos el estatus
   
                Dim message As String = root.Get("message")
            End If
        End If
   
    Catch
        Log(LastException)
    End Try
End Sub

private Sub jobDone (job As HttpJob)
    Try
        Log(job.Success)
        Log(job.GetString)

        If (job.JobName == "CmdGetTicker") Then
            Dim parser As JSONParser
            parser.Initialize(job.GetString)
            Dim root As Map = parser.NextObject
            Dim result As Map = root.Get("result")
            Dim Last As Double = result.Get("Last")
            LastOld = LastNow
            LastNow = Last
            Dim Ask As Double = result.Get("Ask")
            AskOld = AskNow
            AskNow = Ask
            Dim Bid As Double = result.Get("Bid")
            BidOld = BidNow
            BidNow = Bid
            Dim success As String = root.Get("success")
   
            status = success 'Set estatus
   
            Dim message As String = root.Get("message")
        End If

        'Save Time
        TimeOld = DateTime.Now
    Catch
        Log(LastException)
    End Try
End Sub

public Sub Update
    Try
        If (TimeOld + 1000 < DateTime.Now) Then
            Dim uri As String

            uri = "https://bittrex.com/api/v1.1/public/getticker?apikey=" & API_Key & "&market=BTC-ETH"
            SendCommand("CmdGetTicker", uri)
        End If
    Catch
        Log(LastException)
    End Try
End Sub

Ejemplo de uso de la clase:

B4X:
    Dim ETH As money
    API_Key    = "fc10b55fd5014141a6ab3b5b6ce3745c"
    API_Secret = "d499182d9a2542b48d0d248bc5289baa"
    ETH.Initialize("Ethereum", API_Key, API_Secret)
    ETH.Update

¿Porque el código trabaja bien en el Main y en la clase no?

¿Es posible hacer que el programa envié la solicitud de los datos, que la ejecución continúe y que cuando los datos lleguen se ejecute el jobDone como sucede cuando las funciones están en el main?

Saludos.
 

Descartex

Well-Known Member
Licensed User
Longtime User
Buenas.
A simple Vista, solo me chirria esto:
j.Initialize(work, "money")
No deberías pasarle el objeto que gestionara el JobDone y no una String??
Un saludo.
 

Descartex

Well-Known Member
Licensed User
Longtime User
Por ejemplo, el módulo de clase se llama "WorkProcess" le pasarías
B4X:
j.Initialize(WorkProcess,"money")

si la declaración del HttpJob j estuviese en la misma clase, sería:
B4X:
j.Initialize(Me,"money")
 

carlos7000

Well-Known Member
Licensed User
Longtime User
Por ejemplo, el módulo de clase se llama "WorkProcess" le pasarías
B4X:
j.Initialize(WorkProcess,"money")

si la declaración del HttpJob j estuviese en la misma clase, sería:
B4X:
j.Initialize(Me,"money")

Disculpas por contestar tan tarde.

Muchas gracias.

Saludos.
 
Top