HTTPRequest: Auf Ende des Datenempfangs warten

Hier könnt ihr alle Fragen zu SpiderBasic austauschen.
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: HTTPRequest: Auf Ende des Datenempfangs warten

Beitrag von Kurzer »

Kurzer hat geschrieben: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:
Der derzeitige Stand zum Thema HTTPRequests bzw. die Serverkommunikation in ein Modul auszulagern ist bei mir jetzt folgender:

Vor dem Aufruf des Request-Aufrufs (mittels des noch zu erstellenden Moduls) wird eine Prozedur im Main-Scope als Callback-Prozedur registriert. Diese wird dann vom Modul nach dem erfolgreichen Empfangen der Daten vom Server automatisch angesprungen. Die angesprungene Prozedur muss die Callback-Registrierung dann manuell wieder aufheben.
Der unten gezeigte Testcode arbeitet zwar noch nicht als Modul, aber die Bereiche sind trotzdem schon jetzt komplett getrennt.

Die nötigen Schritte, um z.B. einen User einzuloggen und bei Erfolg die Userdaten aus der Datenbank zu erhalten, sind folgende:

Aus dem Main-Scope heraus wird die Callback-Prozedur registriert und dann die entsprechende Kommunikations-Prozedur im Modul angesprungen:

Code: Alles auswählen

	RQ_SetCallback(@ShowData())
	RQ_LoginByEmail("hans@wurst.de", "test")
Nachdem die Daten vom HTTPRequest() geladen worden sind, wird vom Modul automatisch die ShowData() Prozedur aufgerufen.
Diese hebt erst einmal die Callback-Registrierung auf und fragt dann mittels der Modul-Funktion RQ_GetLastResultState() ab, ob die Daten korrekt empfangen und verarbeitet worden sind.
Wenn das der Fall ist, dann holt sie die Daten mittels RQ_GetLastResult() ab und zeigt sie an. Im wirklichen Leben würde sie die Daten dann in ein Listview pumpen oder so.

Code: Alles auswählen

Procedure ShowData()
	RQ_FreeCallback()
	If RQ_GetLastResultState() = #RQ_Data_Processed
		Debug RQ_GetLastResult()
	Else
		Debug "Fehler, Status = " + Str(RQ_GetLastResultState())
	EndIf
EndProcedure
Ich denke, dass das soweit für meine Zwecke erstmal ausreichend gekapselt ist (wenn es als Modul umgesetzt ist).
Hier der Testcode dazu. Nicht wundern, dass die Funktionen LoginByEmail... heißen, aber letzendlich nur ein paar Zeilen Text ausgeben. Es geht nur ums Prinzip und meine PHP-Skripte laufen derzeit nur auf meinem lokalen Rechner, deswegen wird vom HTTPRequest() einfach nur der aktuelle Quelltext angefordert.

Code: Alles auswählen

; ------------------------
; DB Interface-Test Nr. 7
; Kurzer 04.08.2020
; ------------------------

EnableExplicit

Enumeration CallbackEvent #PB_Event_FirstCustomValue
	#RQ_Event_GetLastResult
EndEnumeration

Enumeration ResponseTypes
	#RQ_LoginUser
EndEnumeration

Enumeration ResponseStates
	#RQ_Data_Receiving
	#RQ_Data_Processed
	#RQ_Data_Error
EndEnumeration

Structure structRequest
	iStatus.i
	iCallBack.i
	sProcessedData.s
EndStructure

Global stRequest.structRequest

Procedure HttpGetEvent(iSuccess, sResult.s, iUserData)
	If iSuccess
		Select iUserData
		Case #RQ_LoginUser
			; Hier verarbeiten wir die Daten
			stRequest\sProcessedData = "Daten wurden verarbeitet." + #CRLF$ + Left(sResult, 105)
			stRequest\iStatus = #RQ_Data_Processed
		EndSelect
	Else
		stRequest\sProcessedData = ""
		stRequest\iStatus = #RQ_Data_Error
	EndIf
	PostEvent(#RQ_Event_GetLastResult)
EndProcedure

Procedure RQ_SetCallback(*Callback)
	stRequest\iCallBack = *Callback
	BindEvent(#RQ_Event_GetLastResult, *Callback)
EndProcedure

Procedure RQ_FreeCallback()
	If stRequest\iCallBack <> 0
		UnbindEvent(#RQ_Event_GetLastResult, stRequest\iCallBack)
	EndIf
EndProcedure

Procedure RQ_LoginByEmail(sEmail.s="", sPassword.s="")
	stRequest\iStatus = #RQ_Data_Receiving
	; HTTPRequest(#PB_HTTP_Post, "[...]controllerUsers.php", "command=001&param1=hans@wurst.de&param2=test", @HttpGetEvent(), #RQ_LoginUser)
	HTTPRequest(#PB_HTTP_Get, #PB_Compiler_Filename, "", @HttpGetEvent(), #RQ_LoginUser)
EndProcedure

Procedure.i RQ_GetLastResultState()
	ProcedureReturn  stRequest\iStatus 
EndProcedure

Procedure.s RQ_GetLastResult()
	ProcedureReturn stRequest\sProcessedData
EndProcedure

; ------------------------------------------------------------------------------------
; Alles was oberhalb dieses Kommentars liegt, soll später in ein Modul gepackt werden
; ------------------------------------------------------------------------------------

Procedure ShowData()
	RQ_FreeCallback()
	If RQ_GetLastResultState() = #RQ_Data_Processed
		Debug RQ_GetLastResult()
	Else
		Debug "Fehler, Status = " + Str(RQ_GetLastResultState())
	EndIf
EndProcedure

Procedure Button_LoginByEmail()
	RQ_SetCallback(@ShowData())
	RQ_LoginByEmail("hans@wurst.de", "test")
EndProcedure

; Resize the Debugwindow
! spider_ResizeWindow(spider.debug.window, 0, 0, spider_DesktopWidth(0), spider_DesktopHeight(0))
! spider_ResizeGadget(spider.debug.editorGadget, 5, 5, spider_WindowWidth(spider.debug.window) - 10, spider_WindowHeight(spider.debug.window) - 10)
! spider_StickyWindow(spider.debug.window, 0)

OpenWindow(0, 0, 0, 300, 250, "Test", #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 280, 25, "(1) Request Data")
BindGadgetEvent(0, @Button_LoginByEmail(), #PB_EventType_LeftClick)
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
Antworten