如何在 Meteor Server 上创建一个类似会话的变量?

How to create a session-like variable on Meteor Server?

我想使用 tmp 创建一个 tmp 目录。我想在 Meteor.method 实现中引用此目录的路径...

import tmp from 'tmp';

tmp.dir(function _tempDirCreated(err, path, cleanupCallback) {
 if (err) throw err;

 // Store path as a session variable

});

我知道Session只能在客户端使用,问题是tmp只能在服务端使用

那么,我是否可以在服务器上为 "path variable" 创建一个类似会话的变量,并在服务器 meteor.methods

上访问它

您可以创建一个 Mongo 集合作为您的 temp-cache。由于有方便的包,例如 dburles:mongo-collection-instances,您可以在创建集合的代码中的任何位置访问此集合。

server/main.js

const TempCollection = new Mongo.Collection('temp');

Meteor.startup(()=>{

  // flush all temps at startup
  TempCollection.remove({});

});

server/methods.js

Meteor.methods({

  storeTempDir() {

    const path = // ... get your temp dir from somewhere
    const key =  // ... give this path an id or key

    // the following requires dburles:mongo-collection-instances
    const TempCollection = Mongo.Collection.get('temp');
    TempCollection.insert({key, path});
  },

  doWithTempDir() {

    const key = // ... use a key to access the temp path

    // the following requires dburles:mongo-collection-instances
    const TempCollection = Mongo.Collection.get('temp');
    const path = TempCollection.insert({key});

    // ... do something with your path
  }

}); 

对于更模块化的方法,您还可以围绕此创建一个包装器 class:

server/tmp.js

const TempCollection = new Mongo.Collection('temp');

Meteor.startup(()=>{

  // flush all temps at startup
  TempCollection.remove({});

});

export const tmp = {

  get(key) {
    TempCollection.findOne({key});
  }

  set(key, value) {
    const exist = this.get(key);
    if (exist)
      TempCollection.update(exist._id, { $set: { key, value } });
    else
      TempCollection.insert({key, value});
  }

} 

并像这样在您的方法中使用它:

server/methods.js

import { tmp } from './tmp.js';

Meteor.methods({

  storeTempDir() {

    const path = // ... get your temp dir from somewhere
    const key =  // ... give this path an id or key

    tmp.set(key, path);
  },

  doWithTempDir() {

    const key = // ... use a key to access the temp path

    const path = tmp.get(key).value;

    // ... do something with your path
  }

}); 

关于此的一些评论,以使其简单但安全:

  • 不要将架构附加到 TempCollection,这样您就可以获得真正的 session-like 行为
  • 因为这个集合接受任何东西,请记住它不应该被客户端访问(他们无论如何都可以使用 Session)。
  • 不要发布此内容,因为它可能是关于内部的非常敏感的信息
  • 不要过度使用它。具有深思熟虑的模式的良好数据库设计将受到青睐。
  • 也许已经有实现这种确切行为的软件包。测试和生产准备。这些也要看好。

我找到了解决我的问题的方法:

  1. 流星方法。
  2. Redux 商店。

我正在为 client-side

使用 React

Redux 应该设置一个名为 tmpReducer 的减速器,它具有 dirPath 字段,以及一个用于更改此 dirPath 字段的 redux 操作,名为:changeTmpDirPath

tmpReducer

import { CHANGE_TMP_DIR_PATH } from '../constants/actions';

const INITIAL_STATE = {
  dirPath: ''
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case CHANGE_TMP_DIR_PATH: {
      return { dirPath: action.payload };
    }

    default:
      return state;
  }
};

changeTmpDirPath

import { CHANGE_TMP_DIR_PATH } from '../constants/actions';

export const changeTmpDirPath = path => {
  return { type: CHANGE_TMP_DIR_PATH, payload: path };
};

Then: Create a Meteor method for creating tmp directory [returns DirPath 结果]

Meteor.methods({
  createTmpDir() {
    if (Meteor.isServer) {
      const tmpDir = tmp.dirSync();

      return tmpDir.name;
    }
  }
});

然后

  1. 在客户端启动时调用这个 Meteor 方法。

  2. 将 Meteor 方法调用的结果传递给 Redux 操作,以将 dirPath 存储在应用程序级别状态 [Redux Store]。

     Meteor.call('createTmpDir', function(err, result) {
       if (err) {
         console.log('createTmpDir err', err);
       } else {
         this.props.changeTmpDirPath(result); // Call Redux action
       }
    });
    
  3. 然后 dirPath 将作为 Redux 状态的一部分可用,并准备好传递给任何需要访问它的 Meteor 方法。

    class MyComponent extends React.Component {
    
      componentDidMount() {
        Meteor.call('methodThatNeedDirPath', this.props.tmp.dirPath);
      }
    
      // ...
    
    const mapStateToProps = ({ tmp }) => ({ tmp });
    
    export default connect(mapStateToProps)(MyComponent);