节点中的事件流:在控制台中工作正常,但不写入流

时间:2019-01-12 23:30:17

标签: javascript node.js event-handling czml

我想将事件流式传输到localhost / czml-在控制台或get request窗口中可以正常工作。但是我无法将这些变量流式传输到页面,因为req.query总是最终被未定义

我是编程领域的初学者,大多数时候我不知道自己在做什么(这就是代码如此糟糕的原因...)。我通过反复试验得到了这些代码,并且主要是通过从某个地方进行复制

var express = require('express'),
    fs = require('fs'),
    morgan = require('morgan'),
    path = require('path'),
    os = require('os'),
    http = require('http');

    const app = express();
    const EventEmitter = require('events');
    const stream = new EventEmitter();
    var czmlstream = fs.createWriteStream('czml.czml',{flags: 'a'});


    app.get('/czml', function (req, res, next) {
    //don't log favicon
    if (req.url === '/favicon.ico'){
        res.end();
        return;
    }

    //only log GET and set to stream
    if (req.method === 'GET' ) {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    function createCzml() {
        //get the query value from the request
        var id = req.query.id;
        var lon = parseInt(req.query.lon);
        var lat = parseInt(req.query.lat);
        var alt = parseInt(req.query.alt);

        // custom json format for czml file
        var entity = {
            "id": id,
            "position": {
                "cartographicDegrees": [lat, lon, alt]
            },
            "point": {
                "color" : {"rgba": [0,0,255,255]},
            "pixelSize": 20
            }
        };
        return entity;

    }   
        //first 2 lines for the event stream
    res.write('event: czml\n');
    res.write('data:' + JSON.stringify({ "id":"document", "version":"1.0" })+   
    '\n\n');

    //always tells me that 10 listeners are added .... ?
    stream.setMaxListeners(0);

    //stream.on(req) = emit event on get request?
    stream.on('req', function() {
        res.write('event: czml\n');
        res.write('data:' +JSON.stringify(createCzml)+ '\n\n'); //this 
    doesn't work
    });
    //not sure why this is needed
    stream.emit('req');
    }else{
        res.WriteHead(405, {'Content-Type': 'text/plain'});
        res.end('No GET Request - not allowed');
    }

    //morgan(format, {stream: czmlstream})(req,res,next);   
    }).listen(8000);
    console.log('Server running');

我想要实现的目标: 有人将get请求发送到localhost / czml /?id = 1&lon = -40&lat = 30&alt = 5000 =>这些查询被解析并作为事件流发送到localhost /,格式为:

事件:czml 数据:{json}

我快到了(即使代码很糟糕)-这只是剩下的最后一部分,我必须将这些讨厌的查询写到localhost /无论如何。现在,它可以在控制台中正常记录所有内容,但是未定义的内容会写入localhost /无论如何...

如果您能为我指出正确的方向,我将不胜感激-不过请记住,我需要简单易懂的解释;)

1 个答案:

答案 0 :(得分:0)

好的,我自己解决了这个问题,仅供其他新手参考:

这基本上是this的示例,仅针对获取请求的侦听器(据我的理解)

    // most basic dependencies
var express = require('express')
  , http = require('http')
  , os = require('os')
  , path = require('path')
  , url = require('url')
  , fs = require('fs');

// create the app
var app = express();

// configure everything, just basic setup
//app.set('port', process.env.PORT || 8000);
app.use(function(req, resp, next) {
  resp.header("Access-Control-Allow-Origin", "*");
  resp.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

// Serve the www directory statically
app.use(express.static('www'));

//---------------------------------------
// Handle Get request and event-stream every second
//---------------------------------------
var openConnections = [];

var id, lon, lat, alt;

app.get('/czml', function(req, res, next) {
    //don't log favicon
    if (req.url === '/favicon.ico'){
        res.end();
        return;
    } else {

    var queryData = url.parse(req.url, true).query;
    id = queryData.id;
    lon = queryData.lon;
    lat = queryData.lat;
    alt = queryData.alt;

    req.socket.setTimeout(2 * 60 * 1000);

    // send headers for event-stream connection
    // see spec for more information
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });
    res.write('\n');

    // push this res object to our global variable
    openConnections.push(res);

    // send document packet
    res.write('event: czml\ndata:' + JSON.stringify({ "id":"document", "version":"1.0" })+   '\n\n');

    // When the request is closed, e.g. the browser window
    // is closed. We search through the open connections
    // array and remove this connection.
    req.on("close", function() {
        var toRemove;
        for (var j =0 ; j < openConnections.length ; j++) {
            if (openConnections[j] == res) {
                toRemove =j;
                break;
            }
        }
        openConnections.splice(j,1);
    });
    next();
    }
}).listen(8000);

function createMsg() {
        var entity = {
            "id" : id,
            "position" : {
                "cartographicDegrees": [lon,lat,alt]
            },
            "point" : { 
                "color" : {
                    "rgba" : [0,0,255,255]
                },
                "pixelSize" : 15
            }

        };
        return JSON.stringify(entity);;
    }

setInterval(function() {
    // we walk through each connection
    openConnections.forEach(function(res) {
        // send doc
        res.write('event: czml\n');
        res.write('data:' + createMsg() +   '\n\n');
    });
}, 1000);

我不知道这在这里如何工作-上面的内容实际上不是我的问题的答案-更多的解决方法。但这有效,所以我想很好:)