我试图在Meteor中构建一个简单的多人纸牌游戏,我有两个玩家带有一些牌。现在,当我订阅游戏文档中有玩家及其卡片的游戏集合时,所有浏览器客户端都会所有数据,这很糟糕。
我可以轻松创建客户端过滤器,仅显示该用户的那些卡并隐藏其他卡,但数据已经在浏览器客户端以及任何知道他们在做什么的人可以看到那些数据。编写一个小的客户端脚本来在页面中一直显示它并不难。
我实际上在控制台中发现它不到一分钟,它就在this.Games._collection._docs._map [""]之下,你可以看到两个玩家的所有牌。 ..
我在教程Todo App中看到我们可以过滤要返回的行,这很好。但是,我想知道是否有可能过滤返回的部分文件?
所以,我的问题是:有没有办法只将屏蔽数据发布到客户端?
我的意思是,例如,收集游戏是这样的:
game: {
player1: {
username: "john",
cards: "S8 HA D9 CQ C8"
}
player2: {
username: "mike",
cards: "HQ D7 SK H8 S7"
}
}
" john"的客户应该这样:
game: {
player1: {
username: "john",
cards: "S8 HA D9 CQ C8"
}
player2: {
username: "mike",
cards: "XX XX XX XX XX"
}
}
客户为"迈克" 应该这样:
game: {
player1: {
username: "john",
cards: "XX XX XX XX XX"
}
player2: {
username: "mike",
cards: "HQ D7 SK H8 S7"
}
}
这样的事情是否可能并且仍然是被动的?
或者我是否需要将玩家分成不同的集合,然后过滤用户名/访问权限返回的文件?
但即便如此,我仍然需要屏蔽卡片,因为我仍然需要显示多少张卡"其他"玩家手中没有显示他们是谁......
我猜如果可能的话,这应该是
中的内容Meteor.publish("games", function () {
return Games.find({});
});
但我无法弄清楚要添加什么以使其按照描述的方式工作......
编辑:我认为this section of the Meteor documentation可能会对我有所帮助。我将尝试制作几个奥运会集合的出版物,一个只发布每个人都可以看到的数据,例如每个玩家拥有的卡数,另一个仅在用户被允许看到它时才显示卡片的出版物。
编辑2:嗯。从the Meteor documentation我看到了:
// server: publish the rooms collection, minus secret info.
Meteor.publish("rooms", function () {
return Rooms.find({}, {fields: {secretInfo: 0}});
});
// ... and publish secret info for rooms where the logged-in user
// is an admin. If the client subscribes to both streams, the records
// are merged together into the same documents in the Rooms collection.
Meteor.publish("adminSecretInfo", function () {
return Rooms.find({admin: this.userId}, {fields: {secretInfo: 1}});
});
所以,我试着像这样做:
Meteor.publish("games", function () {
return Games.find({}, {
fields: {
"player1.cards": 0,
"player2.cards": 0
}
});
});
Meteor.publish("playerCards1", function () {
return Games.find({ "player1.userId": this.userId }, {
fields: {
"player1.cards": 1
}
});
});
Meteor.publish("playerCards2", function () {
return Games.find({ "player2.userId": this.userId }, {
fields: {
"player2.cards": 1
}
});
});
当然,在客户端:
Meteor.subscribe("games");
Meteor.subscribe("playerCards1");
Meteor.subscribe("playerCards2");
Games = new Mongo.Collection("games");
但卡现在根本没有通过。好像playerCards1
和playerCards1
发布不起作用......
答案 0 :(得分:0)
我已使用reactive-publish包解决了这个问题:
Meteor.publish("games", function () {
this.autorun(function (c) {
var game = Games.findOne({
$or: [
{ "player1.userId": this.userId },
{ "player2.userId": this.userId }
]
});
if (game) {
if (this.userId === game.player1.userId) {
return Games.find({}, { fields: { "player2.cards": 0 } });
}
if (this.userId === game.player1.userId) {
return Games.find({}, { fields: { "player1.cards": 0 } });
}
return Games.find({ // this will return only one game
$or: [
{ "player1.userId": this.userId },
{ "player2.userId": this.userId }
]
}, {
fields: {
"player1.cards": 0,
"player2.cards": 0
}
});
}
return Games.find({}, { // this will all games
fields: {
"player1.cards": 0,
"player2.cards": 0
}
});
});
});
编辑:今天我意识到如果你有多个正在进行的游戏,这是标准的情况,我的第一个解决方案并不好,因为那么坐在一个游戏中的player1的用户将获得所有游戏中的所有玩家1玩家。所以,我更新了解决问题的答案,以解决这个问题。