No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Recommendations on App architecture

    Help
    4
    20
    688
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • s.molinari
      s.molinari last edited by s.molinari

      @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

      1 Reply Last reply Reply Quote 0
      • beets
        beets @SeRiusRod last edited by

        @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.

        S 1 Reply Last reply Reply Quote 0
        • S
          SeRiusRod @beets last edited by

          @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?

          beets 1 Reply Last reply Reply Quote 0
          • beets
            beets @SeRiusRod last edited by

            @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) ?

            S 1 Reply Last reply Reply Quote 0
            • S
              SeRiusRod @beets last edited by

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

              beets 1 Reply Last reply Reply Quote 0
              • beets
                beets @SeRiusRod last edited by beets

                @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.

                S 2 Replies Last reply Reply Quote 0
                • S
                  SeRiusRod last edited by SeRiusRod

                  I’ve tried with global variables, but I could not make it work.
                  Now I’ve made a separate module for the storage management:

                  // storage.js
                  const fs = require('fs');
                  
                  let settings = null;
                  let devices = null;
                  
                  function getSettings() {
                    try {
                      settings = JSON.parse(fs.readFileSync('./settings.json', 'utf8'));
                    } catch (error) {
                      console.log('settings.json file not found.');
                    }
                    if (!settings)
                      settings = {
                        A: true,
                        B: false,
                      };
                    console.log(settings);
                    return settings;
                  }
                  
                  function setSettings(newSettings) {
                    fs.writeFileSync('./settings.json', JSON.stringify(newSettings));
                  }
                  
                  function getDevices() {
                    try {
                      devices = JSON.parse(fs.readFileSync('./devices.json', 'utf8'));
                    } catch (error) {
                      console.log('devices.json file not found.');
                    }
                    if (!devices) devices = {};
                    console.log(devices);
                    return devices;
                  }
                  
                  function setDevices(newDevices) {
                    fs.writeFileSync('./devices.json', JSON.stringify(newDevices));
                  }
                  
                  module.exports = {
                    settings,
                    devices,
                    getSettings,
                    setSettings,
                    getDevices,
                    setDevices,
                  };
                  
                  // server.js
                  const config = require('./config');
                  
                  var storage = require('./storage.js');
                  const mqtt = require('./mqtt.js')
                  
                  function main() {
                    var settings = storage.getSettings();
                    console.log(`settings ${settings}`);   //Works
                    console.log(`storage.settings ${storage.settings}`); //Doesn't
                  
                    setInterval(function() {
                      console.log('*Timer tick!*');
                    }, 5000);
                  }
                  
                  main();
                  

                  If you look on the two console outputs, the second one is null. And I don’t see why. So now I want to populate storage on mqtt.js, but isn’t available there.

                  1 Reply Last reply Reply Quote 0
                  • S
                    SeRiusRod @beets last edited by

                    @beets said in Recommendations on App architecture:

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

                    Yes, you’re right. I was having a background error that prevented my project to work as intended and that confused me.

                    1 Reply Last reply Reply Quote 0
                    • S
                      SeRiusRod @beets last edited by

                      I’ve made a bare NodeJs backend and setup a global variable for devices storage. That added a socket.io file that periodically sends a device.
                      On the Quasar frontend, I’ve added a boot file and setup one page for receiving the data. But I can’t find why it doesn’t receive anything, and the backend doesn’t inform about client’s connection. Perhaps you can give me a hand:

                      Backend:

                      // socket.js
                      const config = require('./config');
                      
                      const app = require('express')();
                      const http = require('http').Server(app);
                      const io = require('socket.io')(http);
                      
                      console.log('socket: module loaded');   //This is shown
                      
                      app.get('/', (req, res) => {
                        res.status(200).send('This is the backend server.');    //This works
                      });
                      
                      function sendDevice(id) {
                        const device = devices.find((i) => i.id === id);
                        io.emit('device', device);
                      }
                      
                      function updateDevice(id, data) {
                        var device = devices.find((i) => i.id === id);
                        if (!device) devices.push(data);
                        else device = data;
                        pendingCommit = true;
                      }
                      
                      http.listen(config.socketPort, () => {
                        console.log('socket: websocket listening on *:' + config.socketPort);   //This works
                      });
                      
                      // All of this doesn't seem to work
                      io.on('connection', (socket) => {
                        console.log(`socket: client connected with id: ${socket.id}`);
                      
                        socket.on('updateDevice', function(data) {
                          if (!data.id) {
                            console.error('socket: [ERROR] Received a device update request without a correct id.');
                            return;
                          }
                          updateDevice(data.id, data);
                        });
                      
                        setInterval(function() {
                          sendDevice('1');
                        }, 5000);
                      
                        io.on('disconnect', () => {
                          console.log(`socket: client disconnected with id: ${socket.id}`);
                        });
                      });
                      
                      module.exports = {
                        sendDevice
                      };
                      

                      Frontend:

                      // boot/socket.js
                      import io from 'socket.io-client'
                      
                      const socket = io.connect('http://localhost:3002')
                      
                      export default ({ Vue }) => {
                        Vue.prototype.$socket = socket
                      }
                      export { socket }
                      
                      <!-- pages/info.vue -->
                      <template>
                        <q-page padding class="window-height window-width row justify-center">
                          Selected: {{selected}}<br/>  <!-- Shows the correct Id -->
                          Name: {{device.display_name}} <!-- Shows default -->
                          <q-knob
                            readonly
                            v-model="device.battery_level"
                            show-value
                            size="150px"
                            :thickness="0.22"
                            color="green"
                            track-color="green-2"
                            class="q-ma-md"
                          >
                            {{ device.battery_level }}%
                          </q-knob>
                        </q-page>
                      </template>
                      
                      <script>
                      export default {
                        name: 'Info',
                        data () {
                          return {
                            selected: '',
                            settings: [],
                            device: {
                              id: '',
                              display_name: 'Empty',
                              battery_level: '-1'
                            }
                          }
                        },
                        mounted () {
                          this.selected = this.$q.localStorage.getItem('selectedItem')
                      
                          this.$socket.on('device', (data) => {
                            this.device = [...this.device, data]
                          })
                        }
                      }
                      </script>
                      
                      1 Reply Last reply Reply Quote 0
                      • S
                        SeRiusRod last edited by

                        Okey. I was getting a silent Cors error.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post