Shop OBEX P1 Docs P2 Docs Learn Events
Spinneret refresh webpage — Parallax Forums

Spinneret refresh webpage

PodionPodion Posts: 90
edited 2012-07-23 18:05 in Accessories
Hello all,


I wonder why I always need to refresh the webpage to open the user LED on Spinerret ? I use the demo code on http://spinneret.servebeer.com:5000/client/sget.htm


When I click on LED ON the URL changes but the LED does not light. I have to refresh the page and then the LED turn on.

Comments

  • Mike GMike G Posts: 2,702
    edited 2012-07-18 13:04
    Sounds like caching. Do you have the globalCache set to 1? What browser are you using?

    The referenced page shows how to invoke a client get and has nothing to do with LEDs.

    Please post your source code.
  • PodionPodion Posts: 90
    edited 2012-07-19 10:55
    Hello Mike G

    There is all the files I use in my program.
    I use Safari or Google Chrome.

    The globalCache is set to 0... can you tell me what dose it make?
    And can you tell me why I see all the Header code on the webpage?

    This Demo work fine! But now if I want to access this Demo outside of my Home Network on internet what is the next step I have to do?

    Thank you very much for your help!
  • Mike GMike G Posts: 2,702
    edited 2012-07-19 14:55
    The globalCache is set to 0... can you tell me what dose it make?
    globalCache sends a header that tells the browser to save the page locally. On successive requests the page is retrieved from the client not the web server.
    But now if I want to access this Demo outside of my Home Network on internet what is the next step I have to do?
    You must configure your router - assuming you have a router.

    See the port forwarding guide which can be found on the Spinneret tutorial
    http://forums.parallax.com/attachment.php?attachmentid=82190&d=1308163657
  • PodionPodion Posts: 90
    edited 2012-07-19 15:28
    I change the globalCache value and it dose not work. I empty the cache on my web browser and it work but only once.
    The second time I click on LED ON the page load from cache.. whatever globalCache is 1 or 0 do you know why ?
  • Mike GMike G Posts: 2,702
    edited 2012-07-19 16:55
    I change the globalCache value and it dose not work. I empty the cache on my web browser and it work but only once.
    The second time I click on LED ON the page load from cache.. whatever globalCache is 1 or 0 do you know why ?
    No idea, the posed code does contain LED handlers. I'm not sure how you're getting the LED to light unless other code is running on the Spinneret.
  • PodionPodion Posts: 90
    edited 2012-07-19 17:11
    I use the user led on the spinneret.

    check the PIR LED


    {{───────────────────────────────────────────────── 
    Copyright (c) 2011 AgaveRobotics LLC.
    See end of file for terms of use.
    
    
    File....... HTTPServer.spin 
    Author..... Mike Gebhard
    Company.... Agave Robotics LLC
    Email...... mailto:mike.gebhard@agaverobotics.com
    Started.... 11/01/2010
    Updated.... 07/16/2011        
    ───────────────────────────────────────────────── 
    }}
    
    
    {
    About:
      HTTPServer is the designed for use with the Spinneret Web server manufactured by Parallax Inc.
    
    
    Usage:
      HTTPServer is the top level object.
      Required objects:
            • Parallax Serial Terminal.spin
            • W5100_Indirect_Driver.spin
            • S35390A_SD-MMC_FATEngineWrapper.spin
            • Request.spin
            • Response.spin
            • StringMethods.spin
            • S35390A_RTCEngine.spin 
    
    
    
    
    
    
    }
    
    
    
    
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000
    
    
      MAX_PACKET_SIZE = $5C0 '1472   '$800 = 2048
      RxTx_BUFFER     = $800         '$600 = 1536
      TEMP_BUFFER     = $600         '$5B4 = 1460 
      TCP_PROTOCOL    = 01        '$300 = 768 
      UDP_PROTOCOL    = 10        '$200 = 512 
      TCP_CONNECT     = $04          '$100 = 256                 
      DELAY           = $05
      MAX_TRIES       = $05               
    
    
      #0, DONE, PUT, CD
                                               
    
    
    DAT
      mac                   byte    $00, $08, $DC, $16, $F2, $73
      subnet                byte    255, 255 ,255, 0
      gateway               byte    24,122,231,1 
      ip                    byte    169,254,150,62
      port                  word    5555
      remoteIp              byte    24,122,231,195 
      remotePort            word    80
      uport                 word    5050 
      emailIp               byte    0, 0, 0, 0
      emailPort             word    25
      status                byte    $00, $00, $00, $00   
      rxdata                byte    $0[RxTx_BUFFER]
      txdata                byte    $0[RxTx_BUFFER]
      udpdata               byte    $0[TEMP_BUFFER]
      fileErrorHandle       long    $0
      debug                 byte    $0
      lastFile              byte    $0[12], 0
      closedState           byte    00
      openState             byte    00
      listenState           byte    00
      establishedState      byte    00
      closingState          byte    00
      closeWaitState        byte    00 
      lastEstblState        byte    00
      lastEstblStateDebug   byte    00
      udpListen             byte    00
      tcpMask               byte    11
      udpMask               byte    00   
      fifoSocketDepth       byte    $0
      fifoSocket            long    $00_00_00_00
      debugSemId            byte    $00
      debugCounter          long    $00
      stringMethods         long    $00
      closingTimeout        long    $00, $00, $00, $00
      udpLen                long    $00
      time                  byte    "00/00/0000 00:00:00", 0
      httpDate              byte    "Wed, 01 Feb 2000 01:00:00 GMT", 0
      globalCache           byte    $0
      dynamicContentPtr     long    @txdata
    
    
                     
    VAR
      long StackSpace[20]
    
    
    OBJ
      pst           : "Parallax Serial Terminal"
      Socket        : "W5100_Indirect_Driver"
      SDCard        : "S35390A_SD-MMC_FATEngineWrapper"
      Request       : "Request"
      Response      : "Response"
      str           : "StringMethods"
      rtc           : "S35390A_RTCEngine"
    
    
    
    
    PUB Initialize | id, size, st
    
    
      debug := 1    
      SDCard.Start
      stringMethods := str.Start
      Request.Constructor(stringMethods)
      Response.Constructor(stringMethods, @txdata)
    
    
      pst.Start(115_200)
      pause(200) 
    
    
      'Mount the SD card
      pst.str(string("Mount SD Card - ")) 
      SDCard.mount(fileErrorHandle)
      pst.str(string("OK",13))
      
      pst.str(string("Start RTC: "))
      rtc.RTCEngineStart(29, 28, -1)
      
      pause(200)
      pst.str(FillTime)
        
      'Start the W5100 driver
      if(Socket.Start)
        pst.str(string(13, "W5100 Driver Started", 13))
        pst.str(string(13, "Status Memory Lock ID    : "))
        pst.dec(Socket.GetLockId)
        pst.char(13) 
    
    
    
    
      if(debugSemId := locknew) == -1
        pst.str(string("Error, no HTTP server locks available", 13))
      else
        pst.str(string("HTTP Server Lock ID      : "))
        pst.dec(debugSemId)
        pst.char(13)
        
    
    
      'Set the Socket addresses  
      SetMac(@mac)
      SetGateway(@gateway)
      SetSubnet(@subnet)
      SetIP(@ip)
    
    
      ' Initailize TCP sockets (defalut setting; TCP, Port, remote ip and remote port)
      repeat id from 0 to 3
        InitializeSocket(id)
        Request.Release(id)
        pause(50)
    
    
      ' Set all TCP sockets to listen
      pst.char(13) 
      repeat id from 0 to 3 
        Socket.Listen(id)
        pst.str(string("TCP Socket Listener ID   : "))
        pst.dec(id)
        pst.char(13)
        pause(50)
    
    
      pst.Str(string(13,"Started Socket Monitoring Service", 13))
     
      cognew(StatusMonitor, @StackSpace)
      pause(250)
    
    
    
    
      pst.Str(string(13, "Initial Socket States",13))
      StackDump
    
    
      pst.Str(string(13, "Initial Socket Queue",13))
      QueueDump
    
    
      pst.str(string(13,"//////////////////////////////////////////////////////////////",13))
      
      Main
    
    
       
    PUB Main | packetSize, id, i, reset, j, temp
      ''HTTP Service
      repeat
      
        repeat until fifoSocket == 0
        
          bytefill(@rxdata, 0, RxTx_BUFFER)
    
    
          if(debug)
            pst.str(string(13, "----- Start of Request----------------------------",13))
            pause(DELAY)
          else
            pause(DELAY)
            
          ' Pop the next socket handle 
          id := DequeueSocket
          if(id < 0)
            next
          
          if(debug)
            pst.str(string(13,"ID: "))
            pst.dec(id)
            pst.str(string(13, "Request Count     : "))
            pst.dec(debugCounter)
            pst.char(13)
    
    
          packetSize := Socket.rxTCP(id, @rxdata)
    
    
          reset := false
          if ((packetSize < 12) AND (strsize(@rxdata) < 12))
            repeat i from 0 to MAX_TRIES
               'pst.str(string(13,"* Retry *"))
              'Wait for a few moments and try again
              waitcnt((clkfreq/500) + cnt)
              packetSize := Socket.rxTCP(id, @rxdata)
              if(packetSize > 12)
                quit
              if(i == MAX_TRIES)
                'Clean up resource request   
                Request.Release(id)
                Socket.Disconnect(id)
                reset := true
                if(debug)
                  StackDump
                  pst.char(13)
                  QueueDump
                  pst.str(string(13,"* Timeout *",13))
                
          if(reset)
            next
    
    
          Request.InitializeRequest(id, @rxdata)
          
          if(debug)
            pst.char(13)
            HeaderLine1(id)
          else
            pause(DELAY)
    
    
          ' Process router
          Dispatcher(id)
    
    
          'Clean up request resource
          Request.Release(id)
    
    
          ' This starts the close process -> 0x00
          ' use close to force a close
          Socket.Disconnect(id)
    
    
          bytefill(@txdata, 0, RxTx_BUFFER)
    
    
          debugCounter++
    
    
      GotoMain
    
    
    PRI GotoMain
      Main
    
    
    
    
    PRI Dispatcher(id)
            ''Do some processing before sending the response
            if(strcomp(Request.GetName(id), string("led")))
                Led(id)
            if(strcomp(Request.GetName(id), string("post")))
                Post(id)
        
            StaticFileHandler(id)
            return
      
    PRI Post(id) | qstr
            '' Get the post value
            qstr :=  Request.Post(id, string("led"))
            if (strcomp( string("on"), qstr ))
                LedStatus(1)
            else
                LedStatus(0)
                
            return
            
    [COLOR=#ff0000]PRI Led(id) | qstr[/COLOR]
    [COLOR=#ff0000]        '' Get the query string value[/COLOR]
    [COLOR=#ff0000]        qstr :=  Request.Get(id, string("led"))[/COLOR]
    [COLOR=#ff0000]        if (strcomp( string("on"), qstr ))[/COLOR]
    [COLOR=#ff0000]            LedStatus(1)[/COLOR]
    [COLOR=#ff0000]        else[/COLOR]
    [COLOR=#ff0000]            LedStatus(0)[/COLOR]
    
    [COLOR=#ff0000]        return[/COLOR]
    
    [COLOR=#ff0000]PRI LedStatus(state)[/COLOR]
    [COLOR=#ff0000]        dira[23]~~[/COLOR]
    [COLOR=#ff0000]        outa[23] := state[/COLOR]
    [COLOR=#ff0000]        return[/COLOR]
    
    
    PRI StaticFileHandler(id) | fileSize, i, headerLen, temp, j
      ''Serve up static files from the SDCard
      
      'pst.str(string(13,"Static File Handler",13)) 
      SDCard.changeDirectory(@approot)
      pst.char(13)
      
      'Make sure the directory exists
      ifnot(ChangeDirectory(id))
        'send 404 error
        WriteError(id)
        SDCard.changeDirectory(@approot)
        return
        
      ' Make sure the file exists
      ifnot(FileExists(Request.GetFileName(id)))
        'send 404 error
        WriteError(id)
        SDCard.changeDirectory(@approot)
        return
    
    
      ' Open the file for reading
      SDCard.openFile(Request.GetFileName(id), "r")
      fileSize := SDCard.getFileSize
    
    
      'WriteResponseHeader(id)
      'BuildHeader(extension, statusCode, expirer)
      headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
      Socket.txTCP(id, @txdata, headerLen)
      
      if fileSize < MAX_PACKET_SIZE
        ' send the file in one packet
        SDCard.readFromFile(@txdata, fileSize)
        Socket.txTCP(id, @txdata, fileSize)
      else
        ' send the file in a bunch of packets 
        repeat
          SDCard.readFromFile(@txdata, MAX_PACKET_SIZE)  
          Socket.txTCP(id, @txdata, MAX_PACKET_SIZE)
          fileSize -= MAX_PACKET_SIZE
          ' once the remaining fileSize is less then the max packet size, just send that remaining bit and quit the loop
          if fileSize < MAX_PACKET_SIZE and fileSize > 0
            SDCard.readFromFile(@txdata, fileSize)
            Socket.txTCP(id, @txdata, fileSize)
            quit
       
          ' Bailout
          if(i++ > 1_000_000)
            WriteError(id)
            quit
         
      SDCard.closeFile
      SDCard.changeDirectory(@approot)
      return
    
    
    
    
      
    PRI WriteError(id) | headerOffset
      '' Simple 404 error
      pst.str(string(13, "Write 404 Error",13 ))
      headerOffset := Response.BuildHeader(Request.GetExtension(id), 404, false)
      Socket.txTCP(id, @txdata, headerOffset)
      return
    
    
      
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Write data to a buffer
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI PushDynamicContent(content)
      ' Write the content to memory
      ' and update the pointer
      bytemove(dynamicContentPtr, content, strsize(content))
      dynamicContentPtr := dynamicContentPtr + strsize(content)
      return
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' directory and file handlers
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    PRI ChangeDirectory(id) | i, found
      'Handle directory structure for this Request
      if(Request.GetDepth(id) > 1)
        repeat i from 0 to Request.GetDepth(id)-2
          'Return if the directory is not found 
          ifnot(FileExists(Request.GetPathNode(id, i)))
            return false
          found := SDCard.changeDirectory(Request.GetPathNode(id, i))
      return true 
    
    
      
    PRI FileExists(fileToCompare) | filenamePtr
    'Start file find at the top of the list
      SDCard.startFindFile 
      'Verify that the file exists
      repeat while filenamePtr <> 0
        filenamePtr := SDCard.nextFile 
        if(str.MatchPattern(filenamePtr, fileToCompare, 0, false ) == 0 )
          return true
    
    
      return false
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Time Methods and Formats
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI GetTime(id) | ptr, headerOffset
      ptr := @udpdata
      FillHttpDate
      
      bytemove(ptr, string("<p>"),3)
      ptr += 3
    
    
      bytemove(ptr, @httpDate, strsize(@httpDate))
      ptr += strsize(@httpDate)
      
      bytemove(ptr, string("</p>"),4)
      ptr += 3  
    
    
      headerOffset := Response.BuildHeader(Request.GetExtension(id), 200, false)
      Socket.txTCP(id, @txdata, headerOffset)
      StringSend(id, @udpdata)
      bytefill(@udpdata, 0, TEMP_BUFFER)
      
      return
     
     
    PRI FillTime | ptr, num
     'ToString(integerToConvert, destinationPointer)
     '00/00/0000 00:00:00
      ptr := @time
      rtc.readTime
      
    
    
      FillTimeHelper(rtc.clockMonth, ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockDate, ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockYear, ptr)
      ptr += 5
    
    
      FillTimeHelper(rtc.clockHour , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockMinute , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockSecond, ptr) 
     
      return @time
    
    
    
    
    PRI FillHttpDate | ptr, num, temp
     'ToString(integerToConvert, destinationPointer)
     'Wed, 01 Feb 2000 01:00:00 GMT
      ptr := @httpDate
      rtc.readTime
    
    
    
    
      temp := rtc.getDayString
      bytemove(ptr, temp, strsize(temp))
      ptr += strsize(temp) + 2
    
    
      FillTimeHelper(rtc.clockDate, ptr)
      ptr += 3
    
    
      temp := rtc.getMonthString
      bytemove(ptr, temp, strsize(temp))
      ptr += strsize(temp) + 1
    
    
      FillTimeHelper(rtc.clockYear, ptr)
      ptr += 5
    
    
      FillTimeHelper(rtc.clockHour , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockMinute , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockSecond, ptr)
      
      return @httpDate
     
    
    
    PRI FillTimeHelper(number, ptr) | offset
      offset := 0
      if(number < 10)
        offset := 1
         
      str.ToString(@number, @tempNum)
      bytemove(ptr+offset, @tempNum, strsize(@tempNum))
      
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' SDCard Logger
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI AppendLog(logToAppend)
      '' logToAppend:  Pointer to a string of test we'd like to log
      SDCard.changeDirectory(@approot) 
    
    
      if(FileExists(@logfile))
        SDCard.openFile(@logfile, "A")
      else
        SDCard.newFile(@logfile)
    
    
      SDCard.writeData(string(13,10,"----- Start "),14)
      SDCard.writeData(FillTime, 19)
      SDCard.writeData(string(" -----"),6)
      SDCard.writeData(@crlf_crlf, 2)
    
    
      SDCard.writeData(logToAppend, strsize(logToAppend))
      SDCard.writeData(@crlf_crlf, 2)
      
      SDCard.writeData(string("----- End "),10)
      SDCard.writeData(FillTime, 19)
      SDCard.writeData(string(" -----"),6)
      SDCard.writeData(@crlf_crlf, 2)
    
    
      SDCard.closeFile
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Memory Management
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI Set(DestAddress, SrcAddress, Count)
      bytemove(DestAddress, SrcAddress, Count)
      bytefill(DestAddress+Count, $0, 1)
      
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Socekt helpers
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    
    PRI GetTcpSocketMask(id)
      return id & tcpMask
    
    
      
    PRI DecodeId(value) | tmp
        if(01 & value)
          return 0
        if(10 & value)
          return 1
        if(00 & value)
          return 2 
        if(00 & value)
          return 3
      return -1
    
    
    
    
    PRI QueueSocket(id) | tmp
      if(fifoSocketDepth > 4)
        return false
    
    
      tmp := |< id
      
      'Unique check
      ifnot(IsUnique(tmp))
        return false
        
      tmp <<= (fifoSocketDepth++) * 8
      
      fifoSocket |= tmp
    
    
      return true
    
    
    
    
    PRI IsUnique(encodedId) | tmp
      tmp := encodedId & $0F
      repeat 4
        if(encodedId & fifoSocket)
          return false
        encodedId <<= 8
      return true 
        
    
    
    PRI DequeueSocket | tmp
      if(fifoSocketDepth == 0)
        return -2
      repeat until not lockset(debugSemId) 
      tmp := fifoSocket & $0F
      fifoSocket >>= 8  
      fifoSocketDepth--
      lockclr(debugSemId)
      return DecodeId(tmp)
    
    
      
    PRI ResetSocket(id)
      Socket.Disconnect(id)                                                                                                                                 
      Socket.Close(id)
      
    PRI IsolateTcpSocketById(id) | tmp
      tmp := |< id
      tcpMask &= tmp
    
    
    
    
    PRI SetTcpSocketMaskById(id, state) | tmp
    '' The tcpMask contains the socket the the StatusMonitor monitors
      tmp := |< id
      
      if(state == 1)
        tcpMask |= tmp
      else
        tmp := !tmp
        tcpMask &= tmp 
        
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' W5100 Helper methods
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI GetCommandRegisterAddress(id)
      return Socket#_S0_CR + (id * $0100)
    
    
    PRI GetStatusRegisterAddress(id)
      return Socket#_S0_SR + (id * $0100)
    
    
        
    PRI SetMac(_firstOctet)
      Socket.WriteMACaddress(true, _firstOctet)
      return 
    
    
    
    
    PRI SetGateway(_firstOctet)
      Socket.WriteGatewayAddress(true, _firstOctet)
      return 
    
    
    
    
    PRI SetSubnet(_firstOctet)
      Socket.WriteSubnetMask(true, _firstOctet)
      return 
    
    
    
    
    PRI SetIP(_firstOctet)
      Socket.WriteIPAddress(true, _firstOctet)
      return 
    
    
    
    
    
    
    PRI StringSend(id, _dataPtr)
      Socket.txTCP(id, _dataPtr, strsize(_dataPtr))
      return 
    
    
    
    
    PRI SendChar(id, _dataPtr)
      Socket.txTCP(id, _dataPtr, 1)
      return 
    
    
     
    PRI SendChars(id, _dataPtr, _length)
      Socket.txTCP(id, _dataPtr, _length)
      return 
    
    
    
    
    PRI InitializeSocket(id)
      Socket.Initialize(id, TCP_PROTOCOL, port, remotePort, @remoteIp)
      return
    
    
    PRI InitializeSocketForEmail(id)
      Socket.Initialize(id, TCP_PROTOCOL, port, emailPort, @emailIp)
      return
      
    PRI InitializeUPDSocket(id)
      Socket.Initialize(id, UDP_PROTOCOL, uport, remotePort, @remoteIp)
      return
    
    
    
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Debug/Display Methods
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PRI QueueDump
      '' Display socket IDs in the queue
      '' ie 00000401 -> socket Zero is next to pop off
      pst.str(string("FIFO["))
      pst.dec(fifoSocketDepth)
      pst.str(string("] "))
      pst.hex(fifoSocket, 8)
    
    
        
    PRI StackDump | clsd, open, lstn, estb, clwt, clng, id, ulst
      '' This method is purely for debugging
      '' It displays the status of all socket registers
      repeat until not lockset(debugSemId)
      clsd := closedState
      open := openState
      lstn := listenState
      estb := establishedState
      clwt := closeWaitState
      clng := closingState
      ulst := udpListen
      lockclr(debugSemId)
    
    
      pst.char(13) 
      repeat id from 3 to 0
        pst.dec(id)
        pst.str(string("-"))
        pst.hex(status[id], 2)
        pst.str(string(" "))
        pause(1)
    
    
      pst.str(string(13,"clsd open lstn estb clwt clng udps", 13))
      pst.bin(clsd, 4)
      pst.str(string("-"))
      pst.bin(open, 4)
      pst.str(string("-"))
      pst.bin(lstn, 4)
      pst.str(string("-"))  
      pst.bin(estb, 4)
      pst.str(string("-"))  
      pst.bin(clwt, 4)
      pst.str(string("-"))  
      pst.bin(clng, 4)
      pst.str(string("-"))  
      pst.bin(ulst, 4)
      pst.char(13)
       
    PRI HeaderLine1(id) | i
      pst.str(Request.GetMethod(id))
      pst.char($20)
    
    
      i := 0
      repeat Request.GetDepth(id)
        pst.char($2F)
        pst.str(Request.GetPathNode(id, i++))
        
       
    PRI Pause(Duration)  
      waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
      return
    
    
    
    
    PRI StatusMonitor | id, tmp, value
    '' StatusMonitor is the heartbeat of the project
    '' Here we monitor the state of the Wiznet 5100's 4 sockets
      repeat
    
    
        Socket.GetStatus32(@status[0])
    
    
        ' Encode status register states
        repeat until not lockset(debugSemId)
    
    
        closedState := openState := listenState := establishedState := {
         } closeWaitState := closingState := 0
         
        repeat id from 0 to 3
          case(status[id])
            $00: closedState               |= |< id
                 closedState               &= tcpMask  
            $13: openState                 |= |< id
                 openState                 &= tcpMask                   
            $14: listenState               |= |< id
                 listenState               &= tcpMask
            $17: establishedState          |= |< id
                 establishedState          &= tcpMask
            $18,$1A,$1B: closingState      |= |< id
                         closingState      &= tcpMask
            $1C: closeWaitState            |= |< id
                 closeWaitState            &= tcpMask
            $1D: closingState              |= |< id
                 closingState              &= tcpMask
            $22: udpListen                 |= |< id
                 udpListen                 &= udpMask 
    
    
        if(lastEstblState <> establishedState)
          value := establishedState
          repeat while value > 0
            tmp := DecodeId(value)
            if(tmp > -1)
              QueueSocket(tmp)
              tmp := |< tmp
              tmp := !tmp
              value &= tmp
          lastEstblState := establishedState
    
    
        lockclr(debugSemId)
        
        ' Initialize a closed socket 
        if(closedState > 0)
          id := DecodeId(closedState)
          if(id > -1)
            InitializeSocket(id & tcpMask)
        
        'Start a listener on an initialized/open socket   
        if(openState > 0)
          id := DecodeId(openState)
          if(id > -1)
            Socket.Listen(id & tcpMask)
    
    
        ' Close the socket if the status is close/wait
        ' response processor should close the socket with disconnect
        ' there could be a timeout so we have a forced close.
        ' TODO: CCheck for a port that gets stuck in a closing state
        'if(closeWaitState > 0)
          'id := DecodeId(closeWaitState)
          'if(id > -1)
            'Socket.Close(id & tcpMask)
    
    
    
    
    
    
        'pause(100)
    return
        
    DAT
      approot               byte    "\", 0 
      defaultpage           byte    "index.htm", 0
      logfile               byte    "log.txt", 0
      'binFile               byte    "filename.bin", 0
      FS                    byte    "/", 0
      fn                    byte    "filename=", 0
      doublequote           byte    $22, 0
      crlf                  byte    13, 10, 0
      crlf_crlf             byte    13, 10, 13, 10, 0
      uploadfile            byte    $0[12], 0
      uploadfolder          byte    "uploads", 0
      tempNum               byte    "0000",0
      multipart             byte    "Content-Type: multipart/form-data; boundary=",0
      boundary              byte    $2D, $2D
      boundary1             byte    $0[64]
      'loadme                file    "TogglePin0.binary"                 
    
    
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial ions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    
  • PodionPodion Posts: 90
    edited 2012-07-19 17:40
    I think the problem is that the Spinneret always sending cache info. Wen I put Cache disable on Google Chrome it work great !
    But how can I turn off the cache directly on the spinneret to provide those problem whit all user...?
  • PodionPodion Posts: 90
    edited 2012-07-19 18:46
    The Header part is suppose to be at the first line on the .htm document ?
    Maybe i forgot something because all the Header appear on the top of the web browser... and if i delete the Heather it dose nothing.

    In the 14.9 Cache-Control i see "no-cache" it could be a solution ? were can i put the "no-cache" to make it work?
  • PodionPodion Posts: 90
    edited 2012-07-19 19:04
    I replace the "Public" by "no cache" in the DAT of the Response file and this fix my problem.
    OBJ  rtc           : "S35390A_RTCEngine.spin"
      
    CON
      MATCH_PATTERN                 = $03
      TO_STRING                     = $02
      TO_INTEGER                    = $01
      
      '#1, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
      '#1, January, February, March, April, May, June, July, August, September, October, November, December
      
    DAT
      strParams     long    $0
      txdata        long    $0
      conLen        long    $FFFF_FFFF
      getTime       byte    $1
      hashTable     long    $0[30]
      headerMap     long    $0[30]
      extensions    byte    "htm",0,   "xml",0,  "xsl",0,   "shp",0,   "txt",0,  {
      }                     "pdf",0,   "zip",0,  "jpg",0,   "png",0,   "gif",0,  {
      }                     "css",0,   "js", 0,  "ico",0,   "wmv",0,   "wav",0,  {
      }                     "oct",10
      hearerline    byte    "text/html",0,                "text/xml",0,               "text/xml",0,           "text/html",0,       "text/plain; charset=utf-8",0,{
      }                     "application/pdf",0,          "application/zip",0,        "image/jpeg",0,         "image/png",0,       "image/gif",0,                {
      }                     "text/css",0,                 "application/javascript",0, "image/x-icon",0,        "video/x-ms-wmv",0,  "audio/x-wav",0,             {
      }                     "application/octet-stream",0
      header1       byte    "HTTP/1.1 ",0
      server        byte    "Server: Spinneret/2.1", 13, 10, 0
    [COLOR=#ff0000]  cache         byte    "Cache-Control: no-cache", 13, 10, 0[/COLOR]
      contenttype   byte    "Content-Type: ",0
      contentlen    byte    "Content-Length: 5",0
      expires       byte    "Expires: Wed, 01 Feb 2000 01:00:00 GMT", 13, 10, 0
      newline       byte    13, 10, 0
      ok            byte    "200 OK" ,13, 10, 0
      notfound      byte    "404 Not Found", 13, 10, 0
      genError      byte    "<html><head><title>Error</title></head><body><h1>Error</h1></body></html>",0
      tempNum       byte    "0000",0
    
    
    
    
    
    
    PUB Constructor(stringMethods, txbuff)
      strParams := stringMethods
      txdata := txbuff
      InitializeHashIndex
      rtc.RTCEngineStart(29, 28, -1)
      
    
    
    PUB WriteExpireHeader(value)
      getTime := value
    
    
    PUB SetContentLength(value)
      conLen := value    
    
    
    
    
    PRI FillExpireHeader(cachePage) | ptr, offset, temp
     'ToString(integerToConvert, destinationPointer)
     'Expires: Wed, 01 Feb 2000 01:00:00 GMT
      ptr := @expires + 9 
      rtc.readTime
    
    
      offset := -1
      if(cachePage)
        offset := -1  
      
      temp := rtc.getDayString
      bytemove(ptr, temp, strsize(temp))
      ptr += strsize(temp) + 2
    
    
      FillTimeHelper(rtc.clockDate, ptr)
      ptr += 3
    
    
      temp := rtc.getMonthString
      bytemove(ptr, temp, strsize(temp))
      ptr += strsize(temp) + 1
    
    
      FillTimeHelper(rtc.clockYear + offset, ptr)
      ptr += 5
    
    
      FillTimeHelper(rtc.clockHour , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockMinute , ptr)
      ptr += 3
    
    
      FillTimeHelper(rtc.clockSecond, ptr) 
     
      return @expires
    
    
    
    
    PRI FillTimeHelper(number, ptr) | offset
      offset := 0
      if(number < 10)
        offset := 1
         
      ToString(@number, @tempNum)
      bytemove(ptr+offset, @tempNum, strsize(@tempNum))
        
    PUB BuildHeader(extension, statusCode, cachePage) | ptr, idx
    
    
      if(getTime)
        FillExpireHeader(cachePage)
      
      ptr := txdata
      'Header Line 1
      bytemove(ptr, @header1, strsize(@header1))
      ptr += strsize(@header1)
       
      'Status code
      if(statusCode == 404)
        bytemove(ptr, @notfound, strsize(@notfound))
        ptr += strsize(@notfound)
      else
        bytemove(ptr, @ok, strsize(@ok))
        ptr += strsize(@ok)
    
    
      'Content-Type:   
      bytemove(ptr, @contenttype, strsize(@contenttype))
      ptr += strsize(@contenttype)
      idx :=  GetContentType(extension)
      bytemove(ptr, idx, strsize(idx))
      ptr += strsize(idx)
    
    
      'Newline
      bytemove(ptr, @newline, strsize(@newline))
      ptr += strsize(@newline)
    
    
      'Server:
      bytemove(ptr, @server, strsize(@server))
      ptr += strsize(@server)
    
    
      'Cache
      bytemove(ptr, @cache, strsize(@cache))
      ptr += strsize(@cache)
    
    
    
    
      'Content-Length:
      if(conLen > -1)
        bytemove(ptr, @contentlen, strsize(@contentlen))
        ptr += strsize(@contentlen)
        ptr += strsize(ToString(@conLen, ptr))
        
        bytemove(ptr, @newline, strsize(@newline))
        ptr += strsize(@newline)
        
      'Expires:
      bytemove(ptr, @expires, strsize(@expires))
      ptr += strsize(@expires)
    
    
      'Newline - Newline
      bytemove(ptr, @newline, strsize(@newline))
      ptr += strsize(@newline)
    
    
      if(statusCode <> 200)
        bytemove(ptr, @genError, strsize(@genError))
        ptr += strsize(@genError)  
      
      return ptr - txdata
      
    
    
    PUB GetContentType(ptr) | i, hashcode
      hashcode :=  CreateExtensionHash(ptr)
      
      repeat i from 0 to 30
        if HashTable[i] == hashcode
          return  HeaderMap[i]
      
      return 0
      
    
    
    PUB CreateExtensionHash(ptr) | char, t1, i
      t1 := i := 0
      repeat until byte[ptr] == 0
        char := byte[ptr++] 
        t1 |= char << (8 * i++)
    
    
      return t1
        
      
    PUB InitializeHashIndex  | exPtr, headPtr, idx, char, t1, i 
      
      exPtr := @extensions
      headPtr := @hearerline 
      
      idx := 0
    
    
      'Create file extension hash
      repeat until byte[exPtr] == 10 or idx > 29
        i := 0
        HashTable[idx] := 0 
        repeat until byte[exPtr] == 0
          char := byte[exPtr++] 
          HashTable[idx] |= char << (8 * i++)
        idx++
        exPtr++
    
    
      
      'Map the content-type string to the hash table by index
      i := 0
      HeaderMap[i++] := @hearerline
      repeat idx-1
        headPtr += strsize(headPtr) + 1
        HeaderMap[i++] := headPtr
    
    
    
    
    PRI ToString(integerToConvert, destinationPointer)
      long[strParams][0] := $00
      long[strParams][1] := $FFFF_FFFF
      long[strParams][2] := integerToConvert
      long[strParams][3] := destinationPointer
      long[strParams][4] := $00
      long[strParams][5] := $00
    
    
      long[strParams][0] := TO_STRING
    
    
      repeat until long[strParams][0] == $00
      return destinationPointer
    
    
    
    
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial ions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2012-07-19 19:06
    Just thinking out loud....

    As far as getting around the cache, there may be a solution using an iframe tag where the Spinneret is referenced from another page as the iframe contents ... This also has an advantage of not affecting the browser history.

    I'll have to think about it to implement something with the Spinneret, but I have done something similar in the past allowing for bi-directional dynamic data flow between two pages.
  • PodionPodion Posts: 90
    edited 2012-07-19 19:10
    Just thinking out loud....

    As far as getting around the cache, there may be a solution using an iframe tag where the Spinneret is referenced from another page as the iframe contents ... This also has an advantage of not affecting the browser history.

    I'll have to think about it to implement something with the Spinneret, but I have done something similar in the past allowing for bi-directional dynamic data flow between two pages.

    Yes this could be cool !
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2012-07-20 22:12
    If your server ("Spinneret") is on the same domain as the called or referred web page ("Client") then this will sort of work for proof of concept... I still need to migrate this to a Spinneret but I think something like this might be doable. As is, make sure that both files are in the same domain, or for simple testing make sure they are in the same file directory on your computer. They'll run locally also without being placed on the web. ... run the ClientCode.html

    ServerCode.html
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
    
    <script type="text/javascript">        
    var Seconds = -1
    function Send2Client(){
             var msg = document.getElementById('Server2Client').value;                 // Get value to send to Client //
             window.parent.document.getElementById("message").innerHTML = msg;         // Send value to Client via a parent call //
             document.getElementById('Server2Client').value = "";                      // Clear local value
    
    }        
    function StartCounter(){
             if(Seconds == -1){							   // Check if counter has already started	
               setInterval(function(){ incrementCounter() },1000);                     // if not start the counter and increment every second
             }
    
    }
    function incrementCounter(){						           // increment counter and send to Client		
             Seconds++;
             window.parent.document.getElementById("counter").innerHTML = Seconds+" seconds";
    
    }
    function pageupdate(_interval){							   // set the page update interval ; Mainly this is for the 
             setInterval(function(){                                                   // DEMO ... normally the server would poll the data when 
                                 document.getElementById("ClientMessage").innerHTML = window.parent.document.getElementById('Client2Server').value;
             },_interval);                                                             // it wanted to see the Client content.  But in this example
    }                                                                                  // takes place every 1/2 second
    </script>
    
    <html>
    <body onload=pageupdate(500) bgcolor="#E6E6FA">					   <!-- load HTML and start update interval -->	
          This is the Server Side:<br><br>
    
          Message to send to Client: <input type="text" id="Server2Client" name="Sendmsg" /><br>   <!-- submit value to Client -->
          <button type="button" onclick=Send2Client()>Send</button><br>
    
          <button type="button" onclick=StartCounter()>Start Counter</button><br><br>	<!-- start DEMO counter -->
    
          Message received from Client:  
          <div id="ClientMessage"><!-- Client messsage will end up here --></div>          <!-- Show message received from Client -->
    </body>      
    </html>
    


    ClientCode.html
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
    <script type="text/javascript">        
    function GetValueTest(){
             msg =  "message from Server [" + document.getElementById("message").innerHTML + "]\n\r";
             msg += "counter value from Server [" + document.getElementById("counter").innerHTML + "]";
             alert(msg); 
    }
    </script>
    <html>
    
    <!-- --------------------------------------------------------------------------------------------------------------------------- -->
          This is the Client Side:<br>       
          <div id="message">Waiting for message from Server...<!-- Message from Server will end up here --></div><br>  
          <div id="counter">Start Server Counter...<!-- Counter updates from Server will end up here --></div><br> 
    
          Message to send to Server: <input type="text" id="Client2Server" /><br> 
          <!-- This is interactive as you type, the Server 'sees' it based on the polling interval set on the server side
               i.e. when the server wants to see what you are typing -->
    
          <!-- Note: The javascript from the Server is what updates the 'message', 'counter', and reads from 'Client2Server' -->
    <!-- --------------------------------------------------------------------------------------------------------------------------- -->
    
          <!-- Create an iframe window so YOU can 'see' the server ... -->
     
          <!-- Note: normally the iframe would be hidden and only the server could control the outgoing data, but for this proof of concept
               DEMO the ifram is made visible -->
    
     <!-- <iframe src="ServerCode.html" id="frame1" scrolling="no" height=300 style="display:none;" ></iframe><br><br><br> -->
    
          <iframe src="ServerCode.html" id="frame1" scrolling="no" height=300                       ></iframe><br><br><br>
    
          <!-- This just shows that we can get a variable update from the Server Side iframe rather than just HTML parent headers on the Client side-->
          <button type="button" onclick=GetValueTest()>Show data from Server as a javascript variable on the Client</button><br>
    
    </html>
    
  • PodionPodion Posts: 90
    edited 2012-07-20 22:49
    Ok i will try it out

    Thank you !
  • Mike GMike G Posts: 2,702
    edited 2012-07-21 08:50
    Beau,

    I'm probably missing the point. As far as I can tell there are two pages executing JavaScript on the client. Data is passed on the DOM.

    At some point you'll probably want to make an HTTP request which is invoked by the browser. The same caching rules will apply.

    I would use AJAX over an iframe. To get around the cache, insert the current time to the URL querystring.
    <html>
    <head>
    <title>GETing AJAX</title>
    <script language="javascript" type="application/javascript">
    //Gets the browser specific XmlHttpRequest Object
     function getXmlHttpRequestObject() {
    	 if (window.XMLHttpRequest) {
    		 return new XMLHttpRequest();
    	 } else if (window.ActiveXObject) {
    		 return new ActiveXObject("Microsoft.XMLHTTP");
    	 } else {
    		 alert("Your Browser does not support AJAX!\nIt's about time to upgrade don't you think?");
    	 }
     }
    
     //XmlHttpRequest object
     var req = getXmlHttpRequestObject();
     var htmlTarget;
    
    
     function getRequest(resource, elementId) {
     	
    	// handle the case where a querystring is not detected
    	var char = "&";
     	if(resource.indexOf("?", 0) == -1) {
    		char = "?";
    	}
    		
    	 if (req.readyState == 4 || req.readyState == 0) {
    		 req.open("GET", resource + char + 'ms=' + new Date().getTime(), true);
    		 req.onreadystatechange = handleResponse;
    		 htmlTarget = elementId;
    		 req.send(null);
    		 return false;
    	 }
     }
    
     function handleResponse() {
    	 if (req.readyState == 4) {
    
    		 var str = req.responseText;
    		 //alert(str);
    
    		 var placeholder = document.getElementById(htmlTarget);
    		 placeholder.innerHTML = str;
    	 }
     }
    </script>
    </head>
    <body style="background-color:beige;">
    <div style="width:600px;margin:auto;background-color:white;padding:10px;">
      <h1 style="text-align:center;color:blue;">LED</h1>
      <div style="text-align:center;"><a href="index.htm">Hello World</a> | <a href="led.htm">LED</a></div>
    <h2>Query String</h2>
      <p>
      	<a href="led.htm" onClick="return getRequest('aled.htm?led=on', 'placeholder');">LED On </a> :: 
      	<a href="led.htm" onClick="return getRequest('aled.htm?led=off', 'placeholder');">LED Off</a>
      </p>
      <p>LED: <span id="placeholder">State</span></p>
    </div>
    </body>
    </html>
    
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2012-07-21 13:56
    Mike,

    ...an HTTP request happens within an iframe and does not effect the browser history or add or append data to the the parent browser URL tag. You can make the HTTP request dynamic by placing the iframe within a div and change the content with an innerHTML command in javascript.
  • gourdogourdo Posts: 6
    edited 2012-07-23 18:05
    Hello--


    First time poster and new spinneret/propeller user...I have tried to modify your code that is posted on http://spinneret.servebeer.com:5000/gstart/get.htm , and I do not get my local web page any more.

    I ran through all Mike Gs instructions by the numbers, had it working until I added a servo and what I thought was the html adding a button for the servo (on/off)...

    my code looks like :



    PRI Dispatcher2(id)
    ''do some processing before sending the response
    if(strcomp(Request.GetName(id), string("servo")))
    Demo (id)
    StaticFileHandler(id)
    return

    PRI Demo(id) | qstr
    '' Get the query string value
    qstr := Request.Get(id, string("servo"))
    if (strcomp( string("on"), qstr ))
    ServoStatus(1)

    else
    ServoStatus(0)

    return

    PRI ServoStatus(state)
    cognew(MoveMotor(26),@StackSpace4) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7

    'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below
    repeat
    position:=100 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms)
    waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog)
    position:=138 'Start sending 1.38ms servo signal high pulses (Center position)
    waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog)
    position:=50 'Start sending 0.5ms servo signal high pulses (Clockwise position)
    waitcnt(clkfreq+cnt) 'Wait for 1 second (0.5ms high pulses continue to be generated by the other cog)
    position:=225 'Start sending 2.25ms servo signal high pulses (Counterclockwise position)
    waitcnt(clkfreq+cnt)
    return


    PUB MoveMotor(Pin) 'This method outputs a continuous stream of servo signal pulses on "Pin"
    dira[Pin]~~ 'Set the direction of "Pin" to be an output
    repeat 'Send out a continous train of pulses
    outa[Pin]~~ 'Set "Pin" High
    waitcnt((clkfreq/100_000)*position+cnt) 'Wait for the specifed position (units = 10 microseconds)
    outa[Pin]~ 'Set "Pin" Low
    waitcnt(clkfreq/100+cnt) 'Wait 10ms between pulses



    ...the rest of the code is using exactly what Mike had; I did add the requisite StackSpace for the new cogs, the variables, etc....the code loaded on to the Spinneret, I kept the index.htm page as is, then I modified the led.htm web page to look like:


    <html>
    <head>
    <title>GETing to the Server</title>
    </head>
    <body>
    <div style="width:600px;margin:auto;">
    <h1 style="text-align:center;color:blue;">LED</h1>
    <div style="text-align:center;"><a href="index.htm">Hello World</a> | <a href="led.htm">LED</a></div>
    <p><a href="led.htm?led=on">LED On</a> :: <a href="led.htm?led=off">LED Off</a></p>
    <p>LED: <span id="placeholder"></span></p>
    <p><a href="led.htm?servo=on">SERVO On</a> :: <a href="led.htm?SERVO=off">SERVO Off</a></p>
    <p>LED: <span id="placeholder"></span></p>
    </div>
    </div>
    </body>
    </html>

    All the networking pieces worked fine, got the web page, turned on the led via the web server, then I did the above mods and all is no go. I get this message:

    The connection was reset


    The connection to the server was reset while the page was loading.



    Please help!
Sign In or Register to comment.