2014-07-07 79 views
3

我試圖用nodejs,socket.io和sqlite作爲數據庫編寫一個簡單的應用程序。 目前主要用於培訓目的,以瞭解nodejs是如何工作的,看看它是否適合其他項目。NodeJS - sqlite3,數據同步

該應用程序是一個簡單的頁面,只有一個按鈕。 數據庫用於存儲按鈕的狀態(開/關)。 //這是一個要求,因爲這個數據庫可以被其他服務訪問 基本上,頁面顯示當前狀態(數據庫中的最後一條記錄) 當點擊按鈕時,狀態改變,新的狀態被添加到數據庫。 這似乎工作和數據庫更新。

現在,我想通過使用按鈕的顏色來顯示當前狀態,使這些更改可視化。例如,關閉時顯示藍色,開啓時顯示紅色。 我試着用socket.io來處理點擊事件,看起來我可以改變按鈕的顏色,點擊它。

但是,如果頁面被刷新的顏色了(而且似乎我需要刷新頁面,以查看數據庫中更新後的值)

我怎樣才能保持一個頁面的內容(數據顯示和顏色該按鈕)與數據庫同步?

我希望有人能指點我正確的方向。 謝謝,

app.js

var express = require('express'); 
var sqlite3 = require('sqlite3').verbose(); 
var http = require('http'); 
var path = require('path'); 
var mainDB = 'data/mydb'; 
var hbs = require('hbs'); 

var app = express(); 
//all environments 
app.set('port', 3000); 
app.set('view engine', 'html'); 
app.engine('html', hbs.__express); 
app.use(express.bodyParser()); 
app.use(express.static(path.join(__dirname, 'public'))); 

function getStatus(database, callback){ 
    var db = new sqlite3.Database(database); 
    // Get the last record 
    db.get("SELECT * FROM status ORDER BY id DESC LIMIT 1", function(err, all) { 
     console.log("Current status..."+all.status); 
     callback(err, all); 
    }); 
    db.close(); 
} 
function setStatus(database, status){ 
    console.log("Set Status..."+status); 
    var db = new sqlite3.Database(database); 
    db.run("INSERT INTO status(status, time) VALUES(?,?)", status, Date.now()); 
    db.close(); 
} 

app.get('/', function(req, res) { 
    getStatus(mainDB,function(err, json_value) { 
     res.render('index',{title:"Test", status:json_value.status,time:json_value.time}); 
    }); 

}); 


var server = http.createServer(app); 
var io = require('socket.io').listen(server); 

io.sockets.on('connection', function(socket){ 
    socket.on('click', function(htmlID){ 
     getStatus(mainDB,function(err, json_value) { 
      console.log("Button clicked, current status: "+json_value.status) 
      setStatus(mainDB, !json_value.status); 
      io.sockets.emit('updateButton',htmlID); 
     }); 
    }); 

}); 

server.listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

Client.js:

$(document).ready(function() { 

    var socket = io.connect(); 

    $('.box').click(function() { 
     var selectedID = $(this).attr("id"); 
     socket.emit('click', selectedID); 
     updateButton(selectedID); 
    }); 


    function updateButton(selectedID) { 
     $("#" + selectedID).css({ 
      "background": "red" 
     }); 
    } 

    socket.on('updateButton', function (selectedID) { 
     updateButton(selectedID); 
    }); 
}); 

視圖/ index.html中:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="UTF-8"> 
     <title>Test</title> 
     <meta name="viewport" content="width=device-width, initial-scale=1"> 
     <link rel="stylesheet" href="css/style.css"> 
     <script src="js/jquery.min.js"></script> 
     <script src="js/client.js"></script> 
     <script src="/socket.io/socket.io.js"></script> 
    </head> 
    <body> 
     <div class="container"> 
      <h1>{{title}}</h1> 
      <p>Status: {{status}}</p> 
      <p>Time: {{time}}</p> 
       <div class="box" id="alarm">{{status}}</div> 
     </div> 
    </body> 
</html> 

甲的.py創建虛設分貝:

#!/usr/bin/env python 
from datetime import date, datetime 
import sqlite3 
import time 

tables = { 
    'status' : ''' 
    CREATE TABLE status(id INTEGER PRIMARY KEY, 
    status INTEGER, 
    time TIMESTAMP) 
    ''' 
    } 

def create_db(): 
    db = sqlite3.connect("data/mydb") 
    with db: 
     cursor = db.cursor() 
     for tb_name, create_statement in tables.iteritems(): 
      cursor.execute('drop table if exists %s'%tb_name) 
      print "Creating table : %s"%tb_name 
      cursor.execute(create_statement) 
      db.commit() 

     # fake up some data 
     status = 0 
     for i in range(10): 
      status = not status 
      default_values = [status, datetime.now() ] 
      cursor.execute('INSERT INTO status(status, time) values(?,?)', default_values) 
      time.sleep(0.5) 
     db.commit() 
    db.close() 

if __name__ == "__main__": 
    create_db() 
+0

附註。你提到你打算在其他程序中使用sqlite。按照設計,sqlite一次只能由一個程序使用。雖然它是SQL,但實現仍然是 - 讀取和寫入本地文件。通過兩個程序使用它,您將很快遇到引發問題或文件損壞的情況。 – alandarev

+0

謝謝。是的,我知道這可能是一個問題。但在這種情況下它不會成爲問題。只有一個進程會隨時更改數據庫。 – user46624

回答

0

據我所知,Sqlite模塊是用於「內存數據庫」中的,所以當你編寫任何INSERT語句時,它不會被提交,直到你將它寫入磁盤爲止。我正在使用電子和sql.js(sqlite3節點不工作在電子) 和唯一的解決方案,我發現是運行查詢(INSERT ...),導出數據庫(SQL。 js有db.export()方法),然後使用文件系統覆蓋文件。