Skip to content
Snippets Groups Projects
Select Git revision
  • 636dad944e57cbc06bbf5a9df38aeb55e1f715db
  • master default protected
  • leo
  • dex
  • pendulum
  • apfelstruder
  • littlerascal
7 results

view.js

Blame
  • websocketclient.js 4.25 KiB
    /*
    
    line input
    
    */
    
    import {
      Hunkify,
      Input,
      Output,
      State
    } from '../hunks.js'
    
    function WebSocketClient() {
      Hunkify(this)
    
      let debug = false
    
      let dtin = new Input('byteArray', 'data', this)
      this.inputs.push(dtin)
    
      let dtout = new Output('byteArray', 'data', this)
      this.outputs.push(dtout)
    
      // TODO is tackling state sets / updates / onupdate fn's
      // this is hunk -> manager commune ...
      let statusMessage = new State('string', 'status', 'closed')
      let retryCountHandle = new State('number', 'retrycount', 3)
      let resetRetryHandle = new State('boolean', 'retryreset', false)
      let addressState = new State('string', 'address', '127.0.0.1')
      let portState = new State('number', 'port', 2042)
      this.states.push(statusMessage, retryCountHandle, resetRetryHandle, addressState, portState)
    
      // this ws is a client,
      let ws = {}
      let url = 'ws://127.0.0.1:2020'
      this.outbuffer = new Array()
    
      this.init = () => {
        setTimeout(startWs, 500)
      }
    
      resetRetryHandle.onChange = (value) => {
        retryCountHandle.set(3)
        startWs()
        // to actually change the value, we would do:
        // resetRetryHandle.set(value)
      }
    
      let startWs = () => {
        // manager calls this once
        // it is loaded and state is updated (from program)
        url = 'ws://' + addressState.value + ':' + portState.value
        this.log(`attempt start ws at ${url}`)
        ws = new WebSocket(url)
        ws.binaryType = "arraybuffer"
        ws.onopen = (evt) => {
          this.log('ws opened')
          statusMessage.set('open')
        }
        ws.onerror = (evt) => {
          this.log('ws error, will reset to check')
          console.log('ws error:', evt)
          if(debug) console.log(evt)
          statusMessage.set('error')
          setCheck(500)
        }
        ws.onclose = (evt) => {
          this.log('ws close')
          setCheck(500)
        }
        ws.onmessage = (message) => {
          // this should be a buffer
          if(debug) console.log('WS receives', message.data)
          // tricks?
          // ok, message.data is a blob, we know it's str8 up bytes, want that
          // as an array
          let msgAsArray = new Uint8Array(message.data)
          // it's messy, yep!
          let msgAsStdArray = Array.from(msgAsArray)
          if(debug) console.log('WS receive, as an array:', msgAsArray);
          if (dtout.ie && this.outbuffer.length === 0) {
            dtout.put(msgAsStdArray)
          } else {
            this.outbuffer.push(msgAsStdArray)
          }
        }
        statusMessage.set('ws initialized...')
      }
    
      let checking = false
    
      let setCheck = (ms) => {
        if (checking) {
          // noop
        } else {
          setTimeout(checkWsStatus, ms)
          checking = true
        }
      }
    
      let checkWsStatus = () => {
        let retrycount = retryCountHandle.value - 1
        if (retrycount < 1) {
          // give up
          statusMessage.set('not connected')
          retryCountHandle.set(0)
          checking = false
        } else {
          retryCountHandle.set(retrycount)
          checking = false
          this.log('CHECKING STATUS')
          switch (ws.readyState) {
            case WebSocket.CONNECTING:
              this.log('ws is in process of connecting...')
              break
            case WebSocket.OPEN:
              this.log('is open')
              break
            case WebSocket.CLOSING:
              this.log('is closing')
              break
            case WebSocket.CLOSED:
              this.log('is closed, retrying ...')
              startWs()
              break
            default:
              throw new Error('nonsensical result at ws readystate check for ws')
              break
          }
        }
      }
    
      // override default change f'n
      retryCountHandle.onChange = (value) => {
        this.log('retrycount reset')
        retryCountHandle.set(value)
        setCheck(10)
      }
    
      this.loop = () => {
        // something like if(ws !== null && ws.isopen)
        // if we have an open port, and have bytes to send downstream,
        if (ws !== null && ws.readyState === 1) {
          // no buffering
          if (dtin.io()) {
            let arr = dtin.get()
            if(debug) console.log('WS transmission as array', arr)
            let bytesOut = Uint8Array.from(arr)
            // HERE insertion -> buffer.from() ?
            if(debug) console.log("WS sending buffer", bytesOut.buffer)
            ws.send(bytesOut.buffer)
          }
        }
    
        // check if we have outgoing to pass along
        if (this.outbuffer.length > 0 && !dtout.io()) {
          dtout.put(this.outbuffer.shift())
        }
    
      }
    }
    
    export default WebSocketClient