Sails.js Redis如何流式传输数据?

5

我一直在寻找信息,了解如何通过模型 - 控制器 - 视图将Redis连接到Sails.js,我想我已经搞定了。

我的问题是,我认为我不理解Redis的哲学,它的键等等。

我猜我的Redis没有任何键,我的意思是它不像“name:Victor,surname:Garcia”,而是“Victor:García”,没有键,所以我不知道如何在Redis的模型中设置属性。

所以我尝试了不设置属性或仅为整个键设置一个属性(例如“Victor:Garcia:33:Seville:Spain”),但没有结果。

我的模型看起来像这样:

module.exports = {
    schema: false,
    connection: 'redis',
    autoPK: false,
    autoCreatedAt: false,
    autoUpdatedAt: false,
    attributes: {
        ta : 'string',
        // Override toJSON instance method 
        toJSON: function() {
          var obj = this.toObject();
          return obj;
        }
    }
};

我尝试了这个:

Redis.find()
.where({ ta: 'MB:400V:TRAF004:EP:MvMoment' })
.exec(function(err, users) {
     // Do stuff here 
     console.log("User: " + users + " - " + err);
});

实际上,控制台中没有任何结果:

User: - null

无论我在`where`中设置什么,都尝试了像这样做:
模型
module.exports = {
    schema: false,
    connection: 'redis',
    autoPK: false,
    autoCreatedAt: false,
    autoUpdatedAt: false
};

没有属性,而我在控制器中尝试过。
Redis.find()
    .where({ ta: 'MB:400V:TRAF004:EP:MvMoment' })
    .exec(function(err, users) {
         // Do stuff here 
         console.log("User: " + users + " - " + err);
    });

我在谷歌上找到了这个链接:

http://sailsjs.org/#!/documentation/reference/waterline/models/stream.html

我尝试在我的应用程序中执行示例。

模型(Redis.js):

module.exports = {
        schema: false,
        connection: 'redis',
        autoPK: false,
        autoCreatedAt: false,
        autoUpdatedAt: false
    };

控制器:

estStream: function(req,res){

    if (req.param('startStream') && req.isSocket){

        var getSocket = req.socket;

        // Start the stream.  Pipe it to sockets.
        Redis.stream().pipe(getSocket.emit);

    } else {

      res.view();

    }

视图:

<script type="text/javascript">
window.onload = function startListening(){
    socket.on('gotUser',function(data){
      console.log(data+' has joined the party');
    });
};

</script>
<div class="addButton" onClick="socket.get('/monweb/testStream/',{startStream:true})">Stream all the Users !</div>

但是当我点击按钮时,控制台输出的结果如下:
error: Sending 500 ("Server Error") response: 
 TypeError: Object function (ev) {
  if (ev == 'newListener') {
    return this.$emit.apply(this, arguments);
  }

  var args = util.toArray(arguments).slice(1)
    , lastArg = args[args.length - 1]
    , packet = {
          type: 'event'
        , name: ev
      };

  if ('function' == typeof lastArg) {
    packet.id = ++this.ackPackets;
    packet.ack = lastArg.length ? 'data' : true;
    this.acks[packet.id] = lastArg;
    args = args.slice(0, args.length - 1);
  }

  packet.args = args;

  return this.packet(packet);
} has no method 'on'
    at Stream.pipe (stream.js:65:8)
    at module.exports.testStream (/home/victor/gestamp-PRUEBAS/api/controllers/MonWebController.js:1364:24)
    at routeTargetFnWrapper (/home/victor/gestamp-PRUEBAS/node_modules/sails/lib/router/bind.js:178:5)
    at callbacks (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:164:37)
    at param (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:138:11)
    at param (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:135:11)
    at pass (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:145:5)
    at nextRoute (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:100:7)
    at callbacks (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:167:11)
    at /home/victor/gestamp-PRUEBAS/node_modules/sails/lib/router/bind.js:186:7
    at alwaysAllow (/home/victor/gestamp-PRUEBAS/node_modules/sails/lib/hooks/policies/index.js:209:11)
    at routeTargetFnWrapper (/home/victor/gestamp-PRUEBAS/node_modules/sails/lib/router/bind.js:178:5)
    at callbacks (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:164:37)
    at param (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:138:11)
    at param (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:135:11)
    at pass (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/express/lib/router/index.js:145:5) [TypeError: Object function (ev) {
  if (ev == 'newListener') {
    return this.$emit.apply(this, arguments);
  }

  var args = util.toArray(arguments).slice(1)
    , lastArg = args[args.length - 1]
    , packet = {
          type: 'event'
        , name: ev
      };

  if ('function' == typeof lastArg) {
    packet.id = ++this.ackPackets;
    packet.ack = lastArg.length ? 'data' : true;
    this.acks[packet.id] = lastArg;
    args = args.slice(0, args.length - 1);
  }

  packet.args = args;

  return this.packet(packet);
} has no method 'on']

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at emit (events.js:74:15)
    at ModelStream.end (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/waterline/lib/waterline/utils/stream.js:61:10)
    at module.exports.stream (/home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/waterline/lib/waterline/adapter/stream.js:25:66)
    at /home/victor/gestamp-PRUEBAS/node_modules/sails/node_modules/waterline/lib/waterline/query/stream.js:42:20
    at process._tickDomainCallback (node.js:492:13)

抱歉,我知道我对这个还很新,我确定我在做一些事情(或者很多事情)不对,请你帮帮我好吗?我想要从Redis中流式传输数据到视图。我希望能够在视图中看到Redis中的每一个变化。

谢谢大家。


1
  1. 你已经在Redis数据库中有数据了吗?你需要从现有的Redis数据库中获取数据,对吧?
  2. 你可以不用_where_来获取数据:Redis.find().exec(function(err, users) { console.log("User: " + users + " - " + err); }); 那么如果你这样请求数据会怎样呢?
- Bulkin
1个回答

2

您提出了几个问题,让我们逐一回答:

Redis模式格式

Redis支持多种数据结构,其中sails-redis使用set作为索引,二进制字符串用于存储数据。如果数据的一部分可以用作主键,则使用它可以增加系统性能;否则,sails-redis将根据序列自动生成主键。

根据您的定义,您的模式应如下所示:

module.exports = {
  connection: 'your redis connection name'
  attributes: {
    ta : { type: 'string' }
  }
}

要开始使用它,您可以通过创建空控制器使用蓝图API

检索数据

要从Redis获取数据,您可以使用蓝图API通过生成的ID获取数据或者创建一个新的控制器并使用find方法来获取数据。以下是一个示例(抱歉,模型仅称为Data):

module.exports = {
 findByTa: function (req, res) {
   Data.find({ where: { ta: req.param('ta') }}).exec(function (err, result) {
     res.json(result);
   });
 }

您还需要在conf/routes.js中为新控制器函数添加路由。

'GET /data/ta/:ta': 'DataController.findByTa',

数据流

目前 sails-redis 并未实现 stream 方法,这就是你遇到错误的原因。

数据更改通知

要获取数据更改的通知,您需要注册模型的 socket 以接收新实例,并使模型实例(记录)接收更新和删除事件。以下是一个示例控制器,它在模型本身上注册并订阅所有现有实例。

testEvents: function (req, res) {
  if (req.isSocket){
    Data.watch(req); //register on the model
    Data.find({}).exec(function (err, result) {
      Data.subscribe(req.socket, result); // subscribe to model instance
    });  
  }
}

应该为该操作定义一条路由:

'GET /data/testEvents': 'DataController.testEvents'

在客户端,您需要添加一些代码来调用控制器并监听事件:
window.onload = function startListening(){
  io.socket.on('data',function(msg){
    console.log(msg);
  });
  io.socket.get('/data/testEvents');
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接