Recommendations on App architecture



  • I’m having a hard time to jell the approach for my small app. I’ve already done something, but I don’t know how to progress with my requirements.

    Basically I want to do a small web app that discovers some devices via mqtt, then one can set some settings, and then schedule actions on them.
    So it needs a web frontend, that I already made (spa).
    Needs a global data repository for the scheduling info, that I’m not sure how to correctly setup (vuejs -> quasar)
    Needs a background process for receiving mqtt info.
    A main background service for the scheduler runner to send actions via curl.

    How can I make a quasar app (by now I don’t have the need of a mobile app) that still runs mqtt & scheduler even when no page is open in the browser?
    And what’s the correct way in Quasar of setting a global data object? As a plugin?



  • @SeRiusRod - What device are you intending to use? PC? Mobile phone? Tablet? From what I’ve just googled, you’ll need either Electron (for PC) or Cordova (phone/ tablet) to run a “backend” for mqtt.

    Scott





  • Thanks guys for the resources. Anything about running code in the background without any open session?



  • @SeRiusRod said in Recommendations on App architecture:

    Anything about running code in the background without any open session?

    One way is to just allow the electron window to minimize to tray (and launch on startup). I’m not sure you can keep the process running in the background without major headaches, unless you make two separate programs the user has to launch separately. It could be possible, but I’ve used the minimize to tray for similar purposes before and it works well.



  • The fact is that I intent to pack it as a docker container so it is hosted in my Iot server. What I want is that even when I don’t have any computer with that page opened, the scheduler still being running.
    Is there any way of doing this with a single Quasar project?



  • @SeRiusRod - I’m confused. If you have a docker container running on a server, what does that have to do with Quasar on a client’s device?

    Scott



  • @s-molinari Don’t be confused. It’s easy, you pack the web server as a container and serve from a docker server. Then you connect with your browser.
    I’ve already said that this is not a mobile app.

    The aid I’m seeking is to know if I have to run a separate nodejs service with api+mqtt client and then run the quasar app in a separate process, linking both using socket.io for example, or I can do something to have both things on the same quasar project.



  • @SeRiusRod So to be clear, you’re planning on having a docker container that serves an SPA. This SPA is your scheduler interface. You’re not planning at this time to use either electron or cordova/capacitor. Correct so far?

    The confusion comes from the fact that neither mqtt nor curl can run in a user’s browser. You probably could replace curl with fetch / axios, but you’ll probably have cors issues. Thus, you’ll need a backend node process. The node process will run on the server, and the quasar app is running on the client’s device.

    Your structure would then be:

    On the API (server): run mqtt, your scheduler / cron logic, and make curl requests.

    On the quasar app (client): build an interface for scheduling, and POST or send via socket to api.

    You’re correct that you can link the quasar app and api via socket.io, or just use regular polling GET requests. Note that these two “processes” aren’t running on the same machine unless your docker container is running on your desktop as opposed to a raspberry pi or whatever.

    With this approach, your api is always running, and it will execute your scheduler no matter if a quasar page is open or not.

    And to answer your fundamental question, I would probably not try to build these two projects together somehow. You could make your API also serve the html / js / css of the build quasar project, but nginx is better at that and it reduces complexity.



  • Thanks Beets, yes, now that’s correct.

    @beets said in Recommendations on App architecture:

    Thus, you’ll need a backend node process.

    But before I go that approach, let me understand: If some code is added as a module or boot file, that code will not run in the server without the interface being active at the client?

    BTW, i don’t need an API. If i can setup an in memory model, like a vuex store, populate with mqtt info and periodically dump to a json file that would do.
    I have mqtt already running as a module.

    Wouldn’t another boot file work for the scheduler? (If it’s true that is code that runs in the server)



  • @SeRiusRod - Quasar’s boot files aren’t for server-side code or rather don’t run server-side. Boot files get ran at the boot up time of your app and are used to initialize/ setup things like i18n, API connectivity, etc. So, you need an API, either via REST, GraphQL or even Electron to be able to accomplish server-side tasks.

    Scott



  • @SeRiusRod said in Recommendations on App architecture:

    I have mqtt already running as a module.

    Can you show how this code is running? I may have been mistaken and mqtt can run in the browser via websockets. However to accomplish your main goal that the scheduler always runs (and to make sure that two schedulers aren’t running at the same time), you really should architect this app as a node process running on the server and a thin quasar client to display / edit data.



  • @beets said in Recommendations on App architecture:

    Can you show how this code is running?

    Of course:

    /* /src/boot/mqtt.js */
    import Vue from 'vue'
    const bus = new Vue()
    
    const mqtt = require('mqtt')
    
    export default ({ app }) => {
      window.mqtt = mqtt
      const client = mqtt.connect('mqtt://<myserver>')
      window.mqtt.bus = bus
      window.mqttClient = client
    
      client.on('connect', () => {
        console.log('MQTT server connected successfully')
    
        // # means subscribe to all data
        client.subscribe('#', { qos: 0 }, (error) => {
          if (!error) {
            console.log('Subscription successful')
          } else {
            console.log('Subscription failed')
          }
        })
      })
    
      // Receive return data
      client.on('message', (topic, message) => {
        console.log(topic, ': \t\t\t\t', message.toString())
      })
    
      // Disconnect and reconnect
      client.on('reconnect', (error) => {
        console.log('Reconnecting...', error)
      })
      // Link exception handling
      client.on('error', (error) => {
        console.log('Connection failed...', error)
      })
    
      setInterval(function () {
        client.publish('tcc', 'Hello!')
      }, 5000)
    }
    
    export { mqtt }
    

    This is a lightened sample. Not that I have much more. I was still struggling to create a project wide storage to dump the values received.
    But you were completely right. There’s no code executed as long as there is no client connected.

    Now I’m building a nodejs service that receives mqtt info and stores in a json object that is committed to fs. Then it will schedule based on the events in that object, and also serve that json via sockets to the quasar frontend.

    Any suggestions on how to make that global json storage object?



  • @SeRiusRod said in Recommendations on App architecture:

    Any suggestions on how to make that global json storage object?

    Vuex is the typical answer here. It would be a pretty simple store, with likely just one variable called data or whatever. First question is, have you set anything up with vuex (the src/store folder in quasar) ?



  • @beets
    That’s on the web side. But what about the server side?



  • @SeRiusRod Sorry I thought you had that figured out from here:

    stores in a json object that is committed to fs.

    If you’re just looking to store an object, a global variable works fine, unless I’m still misunderstanding.


Log in to reply