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