【问题标题】:How do I subscribe to a model instance in Sails.JS?如何在 Sails.JS 中订阅模型实例?
【发布时间】:2013-11-18 02:17:48
【问题描述】:

我正在尝试使用订阅功能described here。但是,在编辑 /assets/js/app.js 时,我收到此错误:

Uncaught ReferenceError: Room is not defined 

所以,我不完全确定为什么,但它找不到我的模型。这是我的代码:

Room.subscribe(req, [{id: "5278861ab9a0d2cd0e000001"}], function (response) {
  console.log('subscribed?');
  console.log(response);
});

这是在 app.js 的上下文中

(function (io) {

  // as soon as this file is loaded, connect automatically, 
  var socket = io.connect();
  if (typeof console !== 'undefined') {
    log('Connecting to Sails.js...');
  }

  socket.on('connect', function socketConnected() {

    // Listen for Comet messages from Sails
    socket.on('message', function messageReceived(message) {

      ///////////////////////////////////////////////////////////
      // Replace the following with your own custom logic
      // to run when a new message arrives from the Sails.js
      // server.
      ///////////////////////////////////////////////////////////
      log('New comet message received :: ', message);
      //////////////////////////////////////////////////////

    });


    ///////////////////////////////////////////////////////////
    // Here's where you'll want to add any custom logic for
    // when the browser establishes its socket connection to 
    // the Sails.js server.
    ///////////////////////////////////////////////////////////
    log(
        'Socket is now connected and globally accessible as `socket`.\n' + 
        'e.g. to send a GET request to Sails, try \n' + 
        '`socket.get("/", function (response) ' +
        '{ console.log(response); })`'
    );
    ///////////////////////////////////////////////////////////

    // This is the part I added: 
    Room.subscribe(req, [{id: "5278861ab9a0d2cd0e000001"}], function (response) {
      console.log('subscribed?');
      console.log(response);
    });
    //


   });


  // Expose connected `socket` instance globally so that it's easy
  // to experiment with from the browser console while prototyping.
  window.socket = socket;


  // Simple log function to keep the example simple
  function log () {
    if (typeof console !== 'undefined') {
      console.log.apply(console, arguments);
    }
  }


})(

我这样做的方式是否正确?我应该将这个直接存储在 app.js 中吗?

【问题讨论】:

    标签: javascript socket.io sails.js


    【解决方案1】:

    要订阅模型实例,我使用以下实时模型事件模式,其中一些驻留在客户端,一些驻留在服务器上。请记住,客户端不能只订阅自己——您必须向服务器发送一个请求,让它知道您喜欢被订阅——这是安全完成它的唯一方法. (例如,您可能希望发布包含敏感信息的通知——您希望确保连接的套接字在订阅之前有权查看该信息。)

    我将使用一个带有 User 模型的应用示例。假设我想在现有用户登录时通知人们。

    客户端(第一部分)

    在客户端,为简单起见,我将使用/assets/js 文件夹中现有的app.js 文件(如果您在构建应用程序时使用了--linker 开关,则使用/assets/linker/js 文件夹。 )

    要将我的套接字请求发送到assets/js/app.js 内的服务器,我将使用socket.get() 方法。此方法模仿 AJAX “get”请求(即 $.get() )的功能,但使用套接字而不是 HTTP。 (仅供参考:您还可以访问 socket.post()socket.put()socket.delete())。

    代码如下所示:

     
    // Client-side (assets/js/app.js)
    // This will run the `welcome()` action in `UserController.js` on the server-side.
    
    //...
    
    socket.on('connect', function socketConnected() {
    
      console.log("This is from the connect: ", this.socket.sessionid);
    
      socket.get(‘/user/welcome’, function gotResponse () {
        // we don’t really care about the response
      });
    
    //...
    

    服务器端(第一部分)

    UserController.js 中的welcome() 操作中,现在我们实际上可以使用User.subcribe() 方法为该客户端(套接字)订阅通知。

     
    // api/UserController.js
    
    //...
      welcome: function (req, res) {
        // Get all of the users
        User.find().exec(function (err, users) {
          // Subscribe the requesting socket (e.g. req.socket) to all users (e.g. users)
          User.subscribe(req.socket, users);
        });
      }
    
    //...
    

    回到客户端(第二部分)...

    我希望套接字“监听”我要从服务器发送的消息。为此,我将使用:

     
    // Client-side (assets/js/app.js)
    // This will run the `welcome()` action in `UserController.js` on the backend.
    
    //...
    
    socket.on('connect', function socketConnected() {
    
      console.log("This is from the connect: ", this.socket.sessionid);
    
      socket.on('message', function notificationReceivedFromServer ( message ) {
        // e.g. message ===
        // {
        //   data: { name: ‘Roger Rabbit’},
        //   id: 13,
        //   verb: ‘update’
        // }
      });
    
      socket.get(‘/user/welcome’, function gotResponse () {
        // we don’t really care about the response
      });
    
    // ...
    

    回到服务器端(第二部分)...

    最后,我将开始在服务器端发送消息,使用:User.publishUpdate(id);

     
    // api/SessionController.js
    
    //...
      // User session is created
      create: function(req, res, next) {
    
        User.findOneByEmail(req.param('email'), function foundUser(err, user) {
          if (err) return next(err);
    
          // Authenticate the user using the existing encrypted password...
          // If authenticated log the user in...
    
          // Inform subscribed sockets that this user logged in
          User.publishUpdate(user.id, {
            loggedIn: true,
            id: user.id,
            name: user.name,
            action: ' has logged in.'
          });
        });
      }
    //...
    

    您也可以查看Building a Sails Application: Ep21 - Integrating socket.io and sails with custom controller actions using Real Time Model Events 了解更多信息。

    【讨论】:

    • 我还没有机会测试所有这些 - 但仅仅阅读这篇文章就大有帮助。另外,感谢 SailsCast!
    • 是的,谢谢。需要改进sails 文档以更好地解释此特定流程。
    • 请注意,sails API 在 0.10 中发生了变化,Back on the client-side (Part II)... 现在的工作方式有所不同:收听 modelName 而不是 message
    • 由于这是 google 上的一个热门问题,我想我会提到在sails v0.12 中,如果您想观看整个模型,.subscribe 与第二个参数将锁定您的订阅到您连接时已经存在的所有记录。如果您希望客户端收到新记录的通知,您可以使用User.watch(req);,它将通知客户端所有新记录,并自动订阅它们。此外,您可以使用User.subscribe(req.socket, users); 为客户端订阅对现有记录所做的所有更改。
    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 2023-03-14
    • 2017-03-16
    • 2014-09-27
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多