Aktuelle Zeit: 01.10.2020 09:57

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 31.07.2020 23:43 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Moin,

ich hole mir per HTTPRequest() eine JSON kodierte Userliste von einem PHP script.

Das ganze passiert mit folgendem (nicht allein lauffähigen) Codeschnippsel:
Code:
[...]
Global JsonString.s

Procedure HttpGetEvent(Success, Result$, UserData)
   If Success
      JsonString = Result$
   Else
      Debug "Error"
      JsonString = ""
   EndIf
EndProcedure

Procedure ExtractJSON()
   HTTPRequest(#PB_HTTP_Post, "http://127.0.0.1/test/getusers.php", "getusers=all", @HttpGetEvent())
   
   Debug "Get Users"
   Debug JsonString
[...]
EndProcedure

Die ExtractJSON() Prozedur wird auf Knopfdruck ausgeführt.

Das Problem ist, dass beim ersten Aufruf der String 'JsonString' leer ist. Erst beim zweiten Aufruf der Prozedur läuft alles wie gewünscht.

Ich vermute, dass der HTTPRequest() Aufruf wieder zurückkommt, bevor die Übertragung der Daten abgeschlossen ist. Kann das sein?
Demzufolge ist 'JsonString' noch nicht gefüllt, wenn es per Debug ausgegeben wird.

Liege ich damit richtig oder hat das Verhalten eine andere Ursache?

Kurzer

_________________
"Never run a changing system!"
PB 5.72 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 52.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 31.07.2020 23:51 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Wieder ich. Hallo. :D Hab immer noch keinen Plan von Spiderbasic, wohl aber von Javascript.
In Javascript ist fast alles Event-gesteuert. Demnach liegst du wohl mit deiner Annahme richtig. Die Funktion HTTPRequest() wartet nicht bis HttpGetEvent() abgearbeitet wurde, sondern kehrt schon vorher zum normalen Programmfluss zurück.

Tatsächlich ist das auch immer so gewollt und trägt zu einer besseren Benutzererfahrung bei. Denn alle Anfragen an den Server sollten asynchron ablaufen. Nichts sollte den Code ins Stocken geraten lassen, vor allem keine schlechte Internetverbindung oder ein langsamer Server. Denn sobald ein Javascript-Code läuft, stockt im Grunde die ganze Seite.

Lösung: Du solltest alles, was du mit dem Rückgabewert des Servers anstellen willst, einfach in HttpGetEvent tun.

_________________
Ubuntu Gnome 20.04 LTS x64, PureBasic 5.72 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50, 5.60, 5.71b2)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 01.08.2020 17:56 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Danke für die Erklärung, Nic.

Dann werde ich wohl mit Flags arbeiten, die in dem Callback gesetzt werden.
Wenn ich es (zum testen) nun doch seriell haben möchte und auf das Flag warte, welche Art von Warteloop (mit Timeout) sollte ich dann nutzen?

EDIT: Hmm, nee irgendwas passt da nicht.
In folgendem Code warte ich bis der JsonString von der Eventprozedur gefüllt wurde, aber das funktionier so leider nicht.
Muss das so... oder habe ich einen Denkfehler?

Code:
EnableExplicit

Global JsonString.s

Procedure HttpGetEvent(Success, Result$, UserData)
   If Success
      JsonString = Result$
      Debug "Aus der Eventprozedur: " + Left(JsonString, 10)
   Else
      Debug "Error"
      JsonString = "#"
EndIf
EndProcedure

Procedure ExtractJSON()
   JsonString = ""
   HTTPRequest(#PB_HTTP_Get, #PB_Compiler_Filename, "", @HttpGetEvent())
   
   ; Diese While Schleife mal auskommentieren
   While JsonString = ""
      ; Hier kann ich leider kein Delay reinsetzen, weil es das nicht gibt.   
   Wend
   
   Debug "----------------------"
  Debug "Aus der ExtractJSONProzedur: " + Left(JsonString, 10)
EndProcedure

OpenWindow(0, 0, 0, 300, 100, "Read file example", #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 280, 30, "Go")
BindGadgetEvent(0, @ExtractJSON())

_________________
"Never run a changing system!"
PB 5.72 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 52.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 01.08.2020 18:41 
Offline
Benutzeravatar

Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9
Kurzer hat geschrieben:
In folgendem Code warte ich bis der JsonString von der Eventprozedur gefüllt wurde, aber das funktionier so leider nicht.
Muss das so... oder habe ich einen Denkfehler?

ja, denn mit Deiner Schleife blockierst Du den kompletten Programmablauf.

Wikipedia hat geschrieben:
Standardmäßig wird ein Skript innerhalb eines Browsers in Form eines einzigen Threads ausgeführt. Warteschleifen oder lange Berechnungen sind daher in JavaScript-Programmen zu vermeiden.


Grüße ... Peter

_________________
Schrödingers Smiley :):


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 01.08.2020 22:10 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Okay, also alles eventbasiert programmieren.

Mit PostEvent() klappt es jetzt auch:
Code:
EnableExplicit

Enumeration #PB_Event_FirstCustomValue
   #JS_Event_UserslistLoaded
EndEnumeration

Global JsonString.s

Procedure HttpGetEvent(Success, Result$, UserData)
   If Success
      JsonString = Result$
      PostEvent(#JS_Event_UserslistLoaded)
   Else
      Debug "Error"
      JsonString = ""
EndIf
EndProcedure

Procedure GetString()
   JsonString = ""
   HTTPRequest(#PB_HTTP_Get, #PB_Compiler_Filename, "", @HttpGetEvent())
EndProcedure

Procedure ShowString()
  Debug "String: " + Left(JsonString, 10)
EndProcedure

OpenWindow(0, 0, 0, 300, 50, "Test", #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 280, 30, "Go")
BindGadgetEvent(0, @GetString())

BindEvent(#JS_Event_UserslistLoaded, @ShowString())

Irgendwie ist es aber doch recht gewöhnungsbedürftig. Ich wollte mir eigentlich ein Modul schreiben für die Funktionen, die die Daten vom Server holen.

Zum Beispiel ein GetUserlist(List Userlist.Users), welche die Daten vom Server lädt und die als Paramater übergebene Liste damit füllt. Aber da die Funktion nicht zwangsläufig wartet bis die Liste geladen ist, muss ich das wohl anders machen.
Das macht das Auslagern von Funktionalitäten in ein Modul etwas schwer. Das Füllen eines ListViews mit der geladenen Userliste soll z.B. in einer separaten Prozedur oder gar einem separaten Modul realisiert werden.

Hmm, ich glaube ich muss da nochmal ne Nacht drüber schlafen. :roll:

_________________
"Never run a changing system!"
PB 5.72 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 52.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 04.08.2020 14:42 
Offline

Registriert: 30.04.2009 21:21
Hi,

dieses Problem stellt sich mir auch gerade. Das mit dem Postevent() muss ich dann auch mal testen.
Zusätzlich stellt sich mir noch die Frage, kann ich Postevent() nur einmal abfragen oder lässt das auch mehrere Reaktionen des Servers zu?

Um mal das obige Beispiel zu nehmen: Es kommt nicht eine Antwort als JSON String zurück, sondern für jeden User eine eigene Antwort !
Geht das so ?
Falls ja, könnte man ja auch dem User einen Bearteitungsfortschritt mit senden damit er sieht dass sich was im Hintergrund tut. Es könnte sonst der Eindruck entstehen, dass sich die App aufgehängt hat.

Ergänzendes Edit:

Sorry, Edit wieder gelöscht. :oops:

_________________
Wissen schadet nur dem, der es nicht hat !


Zuletzt geändert von MenschMarkus am 04.08.2020 16:11, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 04.08.2020 15:43 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Man kann über einen kleinen Trick auch Strings per PostEvent verschicken.
Wichtig dann wenn mehrere Http Events kommen, bevor die PostEvents verarbeitet sind. Sonst wird der Globale String überschrieben ...

Da muss man eine wenig mit AllocateStructure und FreeStructure arbeiten.

Habs getestet. Was unter Purebasic geht, geht auch unter Spiderbasic
Code:
EnableExplicit

Enumeration #PB_Event_FirstCustomValue
  #JS_Event_UserslistLoaded
EndEnumeration

Procedure AllocateString(String.s)
  Protected *Mem.String
  *Mem = AllocateStructure(String)
  If *Mem
    *Mem\s = String
  EndIf
  ProcedureReturn *Mem
EndProcedure

Procedure.s FreeString(*Mem.String)
  Protected String.s
  If *Mem
    String = *Mem\s
    FreeStructure(*Mem)
  EndIf
  ProcedureReturn String
EndProcedure

Procedure HttpGetEvent(Success, Result$, UserData)
  If Success
    ; Speicher für den String anfordern und diesen in Parameter Data übergeben
    PostEvent(#JS_Event_UserslistLoaded, 0, 0, 0, AllocateString(Result$))
  Else
    Debug "Error"
   
  EndIf
EndProcedure

Procedure GetString()
  HTTPRequest(#PB_HTTP_Get, #PB_Compiler_Filename, "", @HttpGetEvent())
EndProcedure

Procedure ShowString()
  Protected JsonString.s
  ; String Speicher aus EventData holen und den Speicher wiederfreigeben
  JsonString = FreeString(EventData())
  Debug "String: " + JsonString
EndProcedure

OpenWindow(0, 0, 0, 300, 50, "Test", #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 280, 30, "Go")
BindGadgetEvent(0, @GetString())

BindEvent(#JS_Event_UserslistLoaded, @ShowString())

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.7x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf My Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 04.08.2020 16:25 
Offline

Registriert: 30.04.2009 21:21
zu meiner Frage oben: wie lange ist denn der Timeout für eine Antwort des Servers?

Soll heißen, wie lange darf die Verzögerung sein, bis ich bei Mehrfachantwort das nächste php echo/print ausgebe?
Oder muss ich tatsächlich erst auf alle Daten im Server warten, dort speichern und das Ergebnis mit einem mal ausgeben?

_________________
Wissen schadet nur dem, der es nicht hat !


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 04.08.2020 16:54 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Hallo Namensvetter,

wie meinst du das denn genau mit der Mehrfachantwort vom Server?

Ich bin zwar kein Experte, aber ich denke, dass der HTTPRequest-Callback sein Success erst dann liefert, wenn dein sendendes php file beendet worden ist. Ich bin mir auch nicht sicher, ob der Callback mehrfach aufgerufen wird.

Markus

PS: Du kannst dir ein eigenes Protokoll erstellen und dann mehrer HTTPRequest-Anfragen an deinen Server stellen, um eine Große Datenmenge häppchenweise abzuholen.

Da du das PHP Script dann aber mehrmals startest, müsstest du dir serverseitig irgendwie merken, wie viele Datensätze schon gesendet worden sind (oder du gibst Anzahl bereits übertragener Datensätze beim Aufruf des PHP Scripts als Parameter mit). Wenn es sich um eine SQL-Abfrage handelt, kannst du diese dann einfach nochmal ausführen und mit der LIMIT x, y Klausel festlegen welchen Bereich du aus der Ergebnismenge fetchen willst.

_________________
"Never run a changing system!"
PB 5.72 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 52.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: HTTPRequest: Auf Ende des Datenempfangs warten
BeitragVerfasst: 04.08.2020 17:02 
Offline

Registriert: 30.04.2009 21:21
Ich habe es gerade mal getestet. Es ist eigentlich egal wie lange die Abarbeitung von Mehrfachausgaben dauert. Erst wenn das PHP Skript fertig ist und alles geschrieben wurde, wird wohl ein Status 200 gemeldet und dann erst reagiert der SB Callback. Also einzelne Ausgabe der Ergebnisse scheint nicht möglich zu sein, somit auch keine Fortschrittsmitteilung.
Schade eigentlich....

Kurzer hat geschrieben:
wie meinst du das denn genau mit der Mehrfachantwort vom Server?

Na ja, ich lade eine CSV Datei auf den Server die dann abgearbeitet wird. Ich erhalte für jede Zeile eine Antwort die ich an die SB app zurück gebe.

Kurzer hat geschrieben:
PS: Du kannst dir ein eigenes Protokoll erstellen und dann mehrer HTTPRequest-Anfragen an deinen Server stellen, um eine Große Datenmenge häppchenweise abzuholen.

zu aufwändig...da bin ich zu faul zu :wink:
Lieber schätze ich den Zeitaufwand und lass einen Countdown mit laufen, der zeigt die ungefähre Restzeit an.

_________________
Wissen schadet nur dem, der es nicht hat !


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye