Seite 1 von 2
Auf Webserver warten one Absturz des Programms.
Verfasst: 12.12.2015 10:22
von funkheld
Hallo, guten Tag.
Mit diesem Programm warte ich auf Daten vom Webserver mit einem Timer.
Wenn ich den Webserver zu spät einschalte stürzt das Programm vorher ab.
Wie kann ich bitte das vermeiden, das dieses Programm weiter läuft und wenn der Webserver eine Verbindung hat seine Arbeit auf nimmt und wenn er getrennt ist das Programm trotzdem wieder läuft?
Danke.
Gruss
Code: Alles auswählen
Global buffer.l, text_e.s
Declare TimerCallBack(hWnd,Msg,wParam,lParam)
Enumeration
#Window_0
#Editor_0
EndEnumeration
*buffer=AllocateMemory(16384)
InitNetwork()
OpenWindow(#Window_0,1000,200,420,300,"http-Arduino", #PB_Window_SystemMenu)
SetTimer_(WindowID(#Window_0), 77, 500, @TimerCallBack())
EditorGadget(#Editor_0, 10, 60, 300,200)
Repeat
Event = WaitWindowEvent(5)
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
FreeMemory(*Buffer)
Procedure TimerCallBack(hWnd,Msg,wParam,lParam)
Select Msg
Case #WM_TIMER
If wparam = 77
text_e=""
SetGadgetText(#Editor_0, text_e)
*Buffer = ReceiveHTTPMemory("http://192.168.2.105/index.php?paramter=<an")
text_e + PeekS(*Buffer, 1024, #PB_UTF8)+Chr(10)
SetGadgetText(#Editor_0, text_e)
EndIf
EndSelect
EndProcedure
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 12.12.2015 11:08
von edel
Morgen,
auf einen Zeiger zugreifen, ohne vorher geprueft zu haben ob dieser uberhaupt gueltig ist, ist keine gute Idee.
Code: Alles auswählen
*Buffer = ReceiveHTTPMemory("http://192.168.2.105/index.php?paramter=<an")
if *Buffer
text_e + PeekS(*Buffer, 1024, #PB_UTF8)+Chr(10)
SetGadgetText(#Editor_0, text_e)
endif
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 12.12.2015 12:02
von funkheld
Wie kann es machen , das erst Zugriff ist wenn die Verbindung steht ?
Oder gibt es eine andere Lösung ohne Timer? , das der Zugriff zb alle 0.5 Sekunden ist
Danke.
Gruss
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 12.12.2015 12:21
von GPI
Was mir auffällt. Die machst die Variable buffer global, benutzt sie aber nicht. Der Stern gehört zum Namen.
Die Speicherreservierung in der Hauptschleife? Wozu?
In deinen Callback benutzt du ReceiveHTTPMemory() das Ding reserviert dir den Speicher automatisch, nur freigeben musst du ihn - das passiert nicht. Zudem kann die Funktion fehlschlagen, dann bekommst du eine Null zurück. Das passiert bspw. wenn der Server nicht erreichbar ist. Der Timer funktioniert auch nicht so, wie du dir erhoffst. Das Programm wird trotzdem blockiert.
Du müsstest mit #pb_http_asynchronous arbeiten. Dann bekommst du eine ID zurück, nicht den Speicher. Den kannst du dann mit HTTPProgress() und FinishHTTP() benutzen. Mit Progress fragst du ab, wie weit er ist, mit Finish beendest du den Download und bekommst die Adresse mit den Inhalt. Diesen Speicher musst du dann später auch wieder manuell mit FreeMemory freigeben. Schau in der Hilfe unter HTTPProgress mal nach, da ist ein beispiel.
Den ganzen Download packst du am besten in einen Thread, oder benutzt WaitWindowEvent() mit einen Timeout
z.b.:
Code: Alles auswählen
Event=WaitWindowEvent(100)
if event=0
;downloadstuff
else
;normaler kram
endif
Du kannst auch mit AddWindowTimer(#Window, Timer, Timeout) arbeiten und dann beim #pb_event_timer entsprechend reagieren und wenns fertig ist, den Timer auch löschen.
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 12.12.2015 13:41
von funkheld
Hallo, danke für die Info.
Danke.
Gruss
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 13.12.2015 23:26
von helpy
Ich wollte selbst mal wieder ewas üben

und hab das mit einem Thread versucht.
Da ich keinen lokalen Server hier laufen habe, habe ich es mit dem Abruf der eigenen IP-Adresse von
https://api.ipify.org versucht.
Ich habe dadurch wieder etwas über ReceiveHTTPMemory gelernt.
Damit Ihr auch etwas davon habe, stelle ich den unkommentierten Code mal hier her:
Code: Alles auswählen
CompilerIf Not #PB_Compiler_Thread
CompilerError "Program has to be compiled with option <<threadsafe>>!"
CompilerEndIf
DeclareModule Application
EnableExplicit
Declare Main()
End Main()
EndDeclareModule
Module Application
;#ReceiveParameterURL = "http://192.168.2.105/index.php?paramter=<an"
#ReceiveParameterURL = "https://api.ipify.org"
#DelayBetweenDataRequests = 500
#DelayIfNoConnection = 2000
#DelayIfReceivingData = 10
Enumeration ReceiveParameter #PB_Event_FirstCustomValue
#ReceiveEvent_ThreadHasStarted
#ReceiveEvent_Disconnected
#ReceiveEvent_Connected
#ReceiveEvent_Parameter
EndEnumeration
Enumeration ReceiveState 0
#ReceiveState_NoConnection
#ReceiveState_DataRequest
#ReceiveState_DataReceiving
#ReceiveState_DataReceived
#ReceiveState_ConnectionError
#ReceiveState_Pause
EndEnumeration
Enumeration EXIT_CODE 0
#EXITCODE__NO_ERROR
#EXITCODE__NO_NETWORK
#EXITCODE__NO_THREAD
EndEnumeration
Global winMain, gMessage
Procedure AddMessage(Message.s = #Null$)
SetActiveGadget(gMessage)
AddGadgetItem(gMessage, -1, Message)
EndProcedure
Procedure ReceiveParameterThread(ReceiveTimer)
Protected ReceiveState = #ReceiveState_NoConnection
Protected httpConnection, httpStatus, *ReceiveBuffer
Protected ReceivedParameter.s, *StringData
Protected bLastConnectionFailed = #False
If ReceiveTimer < 100 : ReceiveTimer = 100 : EndIf
PostEvent(#ReceiveEvent_ThreadHasStarted)
Repeat
Select ReceiveState
Case #ReceiveState_NoConnection
Delay(#DelayIfNoConnection)
ReceiveState = #ReceiveState_DataRequest
Case #ReceiveState_DataRequest
httpConnection = ReceiveHTTPMemory(#ReceiveParameterURL, #PB_HTTP_Asynchronous)
If httpConnection
If bLastConnectionFailed
bLastConnectionFailed = #False
PostEvent(#ReceiveEvent_Connected)
EndIf
ReceiveState = #ReceiveState_DataReceiving
Else
If Not bLastConnectionFailed
PostEvent(#ReceiveEvent_Disconnected)
bLastConnectionFailed = #True
EndIf
ReceiveState = #ReceiveState_NoConnection
EndIf
Case #ReceiveState_DataReceiving
httpStatus = HTTPProgress(httpConnection)
Select httpStatus
Case #PB_Http_Success : ReceiveState = #ReceiveState_DataReceived
Case #PB_Http_Failed,
#PB_Http_Aborted : ReceiveState = #ReceiveState_ConnectionError
Default : Delay(#DelayIfReceivingData)
EndSelect
Case #ReceiveState_DataReceived
*ReceiveBuffer = FinishHTTP(httpConnection)
If *ReceiveBuffer
ReceivedParameter = Trim( PeekS(*ReceiveBuffer, -1, #PB_UTF8) )
*StringData = AllocateMemory(StringByteLength(ReceivedParameter) + 2)
PokeS(*StringData, ReceivedParameter)
PostEvent(#ReceiveEvent_Parameter, winMain, #PB_Ignore, #PB_Ignore, *StringData)
EndIf
ReceiveState = #ReceiveState_Pause
Case #ReceiveState_ConnectionError
FinishHTTP(httpConnection)
If Not bLastConnectionFailed
PostEvent(#ReceiveEvent_Disconnected)
bLastConnectionFailed = #True
EndIf
ReceiveState = #ReceiveState_NoConnection
Case #ReceiveState_Pause
Delay(ReceiveTimer)
ReceiveState = #ReceiveState_DataRequest
EndSelect
ForEver
EndProcedure
Procedure Main()
Protected ExitCode = #EXITCODE__NO_ERROR
Protected winClose = #False
Protected winEvent
Protected bThreadStarted
Protected *EventData
If Not InitNetwork()
MessageRequester( "ERROR", "Network functions could not be initialized!" )
ProcedureReturn #EXITCODE__NO_NETWORK
EndIf
winMain = OpenWindow(#PB_Any, 0,0, 400, 300, "Receive Parameter ...", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
gMessage = EditorGadget(#PB_Any, 8,8, 400-16, 300-16, #PB_Editor_ReadOnly)
AddMessage("Programm started!")
AddMessage("Starting thread ...")
If Not CreateThread(@ReceiveParameterThread(), #DelayBetweenDataRequests)
MessageRequester( "ERROR", "Could not start thread!" )
ProcedureReturn #EXITCODE__NO_THREAD
EndIf
Repeat
winEvent = WaitWindowEvent()
Select winEvent
Case #PB_Event_CloseWindow : winClose = #True
Case #ReceiveEvent_ThreadHasStarted
AddMessage("Thread was successfully started!" )
Case #ReceiveEvent_Disconnected
AddMessage("Lost connection!")
AddMessage("Waiting for new connection ...")
Case #ReceiveEvent_Connected
AddMessage("Connected to server!")
Case #ReceiveEvent_Parameter
*EventData = EventData()
If *EventData
If MemorySize(*EventData)
AddMessage( PeekS(*EventData) )
EndIf
FreeMemory( *EventData )
EndIf
EndSelect
Until winClose
ProcedureReturn ExitCode
EndProcedure
EndModule
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 14.12.2015 12:53
von funkheld
Hallo, guten Tag.
Das ist ja ein tolles Programm.
Es läuft bei mir wunderbar mit dem WLan vom Arduino-Yun und mit dem Lan1 am Router mit dem Arduino MEGA2560.
Danke.
Gruss
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 14.12.2015 14:32
von helpy
Hi,
Ich hoffe, dass ich nun den Lerneffekt bei dir nicht verwirkt habe.
Ich versuche alles so gut es geht ohne Hilfe zu machen und frage nur im letzten Moment nach. Ich stöbere da schon mal längere Zeit in der PureBasic Hilfe oder auch im Forum. Auf diesem Weg lerne ich mehr und es prägt sich auch besser ein.
Gruß,
Guido
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 14.12.2015 15:31
von funkheld
Soweit, was du da alles reingebracht hast, hätte ich nicht zusammen bekommen.
Dieses mit Server/Client/http und Thread usw packe ich nicht.
Nur die Beispiele die bei Purebasic dabei sind, die begreife ich.
Ansonsten wenn es in eine Schleife mit Event usw ablaufen soll bekomme ich es nicht hin.
Wo packt man dieses bitte am besten in dein Programm: (Wert ist ein String)
ReceiveParameterURL = "
http://192.168.2.105/index.php?paramter="+wert
Wenn sich der Wert immer ändert ?
Danke.
Gruss
Re: Auf Webserver warten one Absturz des Programms.
Verfasst: 14.12.2015 22:11
von Imhotheb
Hier ein Beispiel mit SetUrlPart()
Code: Alles auswählen
Define Url.s = "http://localhost"
; Datei / Ordner hinzufügen
Url = SetURLPart(Url, #PB_URL_Path, "test.php")
Debug Url
; Parameter hinzufügen
Url = SetURLPart(Url, "Param1", "Value1")
Debug Url
; Parameter hinzufügen
Url = SetURLPart(Url, "Param2", "Value2")
Debug Url
; Parameter ändern
Url = SetURLPart(Url, "Param1", "NewValue")
Debug Url