2016-03-17 38 views
6

Używam express-ws https://www.npmjs.com/package/express-ws (API, który pomaga w tworzeniu serwera dla klientów ekspresowych i websocket).express-ws jak okresowo sprawdzić niestandardowe zdarzenie i podjąć działanie automatycznie

app.ws('/', function(ws, req) { 
    console.log("New connection") 
    if (content.length > 0) { 
    console.log(content) 
    ws.send(content) 
    } 
    ws.on('message', function(msg, flags) { 
    console.log("Received "+ msg); 
    }); 
    ws.on('data', function(msg, flags) { 
    var data = []; // List of Buffer objects 
    res.on("data", function(chunk) { 
     data.push(chunk); // Append Buffer object 
     console.log(data) 
    }) 
    }) 
}); 

Teraz, jak widać z kodem powyżej, gdy połączenie jest go stworzył sprawdza długość treści i wysyła conetent do klienta, jeśli więcej niż 0.

następujący kod routera, na żądanie strony internetowej, aktualizuje plik. Problem z tym, jeśli kiedyś po utworzeniu połączenia, jeśli ten plik został zmodyfikowany, to połączenie nie wie o nim i dlatego funkcja wysyłania nie jest wywoływana. Próbowałem także fs.watch, ale nie mogę go uruchomić.

router.post('/run_restart', function(req, res, next) { 
    text = '{"to_do": "run_test", "devices":"all", "argv": { "test": "' + req.body.cmd + '", "cycles": "' + req.body.cycles + '", "awake_for": "' + req.body.wt + '" }}' 
    path = process.env['HOME']+'/Desktop/automation/Stressem/StressemWeb/bin/task.txt' 
    fs.writeFile(path, text) 
    res.render('home.jade', { title: 'Stressem' }); 
}); 

fs.watch(file, function (event) { 
    fs.stat(file, function (err, stats) { 
    if(stats.size>80){ 
     console.log("Event: " + event); 
     fs.readFile(file, 'utf8', function (err, data) { 
     if (err) throw err; 
     content = data.toString(); 
     }); 
    } 
    }); 

To, co chciałbym, to zawsze, gdy plik jest aktualizowany, można wywołać ws.send dla jednego z połączeń websocket.

Odpowiedz

2

rozwiązany to coś jak ten

var conn_array = []; 
app.ws('/', function(ws, req) { 
    conn_array.push(ws) 
    console.log("New connection") 

    fs.readFile(file, 'utf8', function (err, data) { 
     if (err) throw err; 
     content = data.toString(); 
     if (content.length > 0) { 
      console.log(content.length) 
      conn_array[0].send(content) 
     } 
    }); 


    ws.on('message', function(msg, flags) { 
     console.log("Received "+ msg); 
    }); 

    ws.on('data', function(msg, flags) { 
     var data = []; // List of Buffer objects 
     res.on("data", function(chunk) { 
      data.push(chunk); // Append Buffer object 
      console.log(data) 
     }) 
    }) 
}); 

function readFile(){ 
    console.log("I am here") 
    fs.readFile(file, 'utf8', function (err, data) { 
     if (err) throw err; 
     content = data.toString(); 
     if (content.length > 0 && conn_array.length>0) conn_array[0].send(content); 
    }) 
} 

var interval = setInterval(readFile, 100000); 

teraz mam przyjąć, że jest tylko jeden klient

2

Ten prosty kod działa dobrze z ekspresowym. Jeśli kilka opóźnień nie stanowi problemu, możesz z niego skorzystać.

setInterval(milisecondsToCheck, checkFunction) 

dłużej

http://www.w3schools.com/jsref/met_win_setinterval.asp

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval

jeśli używasz go w ten sposób można zakończyć ją po swojej pracy wykonanej:

var timer = setInterval(milisecondsToCheck, checkFunction); 

aby je wyczyścić:

clearInterval(timer); 
+0

Dziękuję Ci rtime patrząc na to. Ale problem pozostaje ten sam. Jak mogę wywołać tę funkcję dla określonego połączenia? –

+0

sprawdź to http://stackoverflow.com/questions/9935920/how-to-write-a-node-js-function-that-waits-for-an-event-to-fire-before-returnin – bmavus

4

Ponieważ Twój serwer to ten, który zmienia plik, nie musisz używać fs.watch, ponieważ wiesz już, kiedy plik się zmienia. Pozostaje tylko przetestować listę otwartych połączeń i wysłać im nową zawartość.

var connections = []; // Keeps track of all connections 
app.ws('/', function(ws, req) { 
    console.log("New connection") 
    connections.push(ws); // Add the new connection to the list 

    if (content.length > 0) { 
    console.log(content) 
    ws.send(content) 
    } 
    ws.on('message', function(msg, flags) { 
    console.log("Received "+ msg); 
    }); 
    ws.on('data', function(msg, flags) { 
    var data = []; // List of Buffer objects 
    res.on("data", function(chunk) { 
     data.push(chunk); // Append Buffer object 
     console.log(data) 
    }) 
    }) 
    // TODO: Make sure you remove closed connections from `connections` 
    // by listening for the ws `close` event. 
}); 

router.post('/run_restart', function(req, res, next) { 
    text = '{"to_do": "run_test", "devices":"all", "argv": { "test": "' + req.body.cmd + '", "cycles": "' + req.body.cycles + '", "awake_for": "' + req.body.wt + '" }}' 
    path = process.env['HOME']+'/Desktop/automation/Stressem/StressemWeb/bin/task.txt' 
    fs.writeFile(path, text) 
    res.render('home.jade', { title: 'Stressem' }); 

    connections.forEach(function(c){ 
    c.send(text); // Send the new text to all open connections 
    } 
}); 

Uwaga: to nie będzie działać, jeśli masz wiele procesów lub serwerów, ale skoro piszesz do lokalnego systemu plików zamiast z bazy danych, zakładam, to nie jest to wymóg.