// GreenhouseOS — MQTT SharedWorker // Tüm sekmeler bu worker'ı paylaşır — sayfa geçişinde bağlantı kopmaz var mqttLoaded = false; var mqttClient = null; var ports = []; var config = null; var subscriptions = [ 'greenhouse/sensors/#', 'greenhouse/alerts', 'greenhouse/status/#', 'greenhouse/control/#', 'greenhouse/weather/#' ]; // Worker'a bağlanan her sayfa bir port açar self.onconnect = function(e) { var port = e.ports[0]; ports.push(port); port.onmessage = function(event) { var msg = event.data; if (msg.type === 'init') { // Sayfa MQTT ayarlarını gönderdi config = msg.config; if (!mqttClient || !mqttClient.connected) { loadMqttAndConnect(); } else { // Zaten bağlı — durumu bildir port.postMessage({type:'status', connected:true, broker:config.broker}); } } if (msg.type === 'publish') { if (mqttClient && mqttClient.connected) { mqttClient.publish(msg.topic, JSON.stringify(msg.payload), {qos: msg.qos || 1}); } else { port.postMessage({type:'offline', topic:msg.topic}); } } if (msg.type === 'disconnect') { var idx = ports.indexOf(port); if (idx >= 0) ports.splice(idx, 1); } }; port.start(); }; function broadcast(data) { ports.forEach(function(p) { try { p.postMessage(data); } catch(e) {} }); } function loadMqttAndConnect() { if (typeof mqtt !== 'undefined') { doConnect(); return; } // mqtt.min.js'i worker içine yükle try { importScripts('https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.min.js'); doConnect(); } catch(e) { broadcast({type:'error', message:'MQTT kütüphanesi yüklenemedi: ' + e.message}); } } function doConnect() { if (!config) return; var protocol = config.useSSL ? 'wss' : 'ws'; var port = config.useSSL ? config.wssPort : config.wsPort; var url = protocol + '://' + config.broker + ':' + port + '/mqtt'; var clientId = 'greenhouse_worker_' + Math.random().toString(16).substr(2,8); var opts = { clientId: clientId, clean: true, connectTimeout: 8000, reconnectPeriod: 5000, // Worker otomatik yeniden bağlanır keepalive: 60 }; if (config.username) opts.username = config.username; if (config.password) opts.password = config.password; broadcast({type:'status', connected:false, message:'Bağlanıyor: ' + url}); try { mqttClient = mqtt.connect(url, opts); mqttClient.on('connect', function() { broadcast({type:'status', connected:true, broker:config.broker}); subscriptions.forEach(function(topic) { mqttClient.subscribe(topic, {qos:1}); }); }); mqttClient.on('message', function(topic, payload) { try { var data = JSON.parse(payload.toString()); broadcast({type:'message', topic:topic, payload:data}); } catch(e) {} }); mqttClient.on('error', function(err) { broadcast({type:'status', connected:false, message:'Hata: ' + (err.message||'bilinmiyor')}); }); mqttClient.on('close', function() { broadcast({type:'status', connected:false, message:'Bağlantı kesildi, yeniden bağlanıyor...'}); }); mqttClient.on('reconnect', function() { broadcast({type:'status', connected:false, message:'Yeniden bağlanıyor...'}); }); } catch(e) { broadcast({type:'error', message:'Bağlantı hatası: ' + e.message}); } }