如何在流星服务器上创建一个类似会话的变量?



我想使用 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
});

我知道会话仅在客户端上可用,而tmp仅在服务器上可用。

那么,无论如何,我可以在服务器上为"路径变量"创建一个类似会话的变量,并在服务器上访问它。

您可以创建一个充当临时缓存的 Mongo 集合。由于存在方便的包,例如 dburles:mongo-collection-instances,因此您可以在代码中创建集合的任何位置访问此集合。

服务器/主服务器.js

const TempCollection = new Mongo.Collection('temp');
Meteor.startup(()=>{
// flush all temps at startup
TempCollection.remove({});
});

服务器/方法.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
}
}); 

对于更加模块化的方法,您还可以围绕以下内容创建一个 Wrapper 类:

服务器/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});
}
} 

并在您的方法中使用它,如下所示:

服务器/方法.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)。
  • 不要发布此内容,因为它可能是有关内部的非常敏感的信息
  • 不要过度使用它。一个好的数据库设计,一个经过深思熟虑的模式是值得青睐的。
  • 也许已经有包实现了这种确切的行为。经过测试和生产就绪。这些也值得青睐。

我找到了一种解决方案,可以使用以下内容解决我的问题:

  1. 流星法。
  2. Redux 存储。

我在客户端使用 React

Redux 应该使用一个名为tmpReducer的化简器进行设置,该化简器具有 dirPath 字段,以及用于更改此 dirPath 字段的 redux 操作,称为:changeTmpDirPath

tmp减速机

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 };
};

然后:创建一个用于创建 tmp 目录的 Meteor 方法 [返回 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);
    

相关内容

最新更新