我正在使用Meteor流构建实时游戏。我只需要更新一个客户端 - 从服务器发送一个房间ID。用户未登录,因此Meteor.userId()为null,因此我无法使用此:http://arunoda.github.io/meteor-streams/communication-patterns.html#streaming_private_page
只有一个URL(主页)可以发生所有事情。所以我不使用任何URL参数的空间。一切都在服务器上。
我曾尝试使用Meteor.uuid()而不是Meteor.userId(),但每次发射后都会更改uuid(这很奇怪)。
在socket.io中我会这样做:
//clients is an array of connected socket ids
var clientIndex = clients.indexOf(socket.id);
io.sockets.socket(clients[clientIndex]).emit('message', 'hi client');
有没有办法在流星流或流星本身中做到这一点?
答案 0 :(得分:1)
我认为像登录一样使用Meteor.onConnection()可以让你在发布功能中轻松地做你想做的事。
这样的事情:
Messages = new Meteor.Collection( 'messages' );
if ( Meteor.isServer ){
var Connections = new Meteor.Collection( 'connections' );
Meteor.onConnection( function( connection ){
var connectionMongoId = Connections.insert( connection );
//example Message
Message.insert( {connectionId: connection.id, msg: "Welcome"});
//remove users when they disconnect
connection.onClose = function(){
Connections.remove( connectionMongoId );
};
});
Meteor.publish( 'messages', function(){
var self = this;
var connectionId = self.connection.id;
return Messages.find( {connectionId: connectionId});
});
}
if ( Meteor.isClient ){
Meteor.subscribe('messages');
Template.myTemplate.messages = function(){
//show all user messages in template
return Messages.find();
};
}
我在这里使用过数据库支持的集合,因为它们是默认值,但数据库不是必需的。无论何时插入新消息,使消息成为集合都会使响应式发布变得容易。
这与流不同的一种方式是,发送到所有客户端的所有消息最终都会保留在服务器内存中,因为它会尝试跟踪发送的所有数据。如果这确实不合适,那么你可以使用Meteor.method来代替发送数据,只需使用publish来通知用户新的消息可用,所以调用方法并获取它。
无论如何,这就是我的开始。
答案 1 :(得分:1)
嗯,如果您决定使用数据库,这可以轻松完成,但我想如果您拥有大量客户端,这不是最佳选择。
另一种实现这一目标的方法 - 没有数据库 - 就是要充分利用Meteor的publish/subscribe
机制。基本上它的工作方式如下:
1. client asks server for a communication token (use Meteor.methods)
2. client subscribes to some (abstract) data set using that token
3. server publishes the required data based on the received token
因此,您需要在为新用户生成令牌的服务器上定义一个方法(比如说getToken
)(因为您不想使用accounts
)。这可能或多或少是这样的:
var clients = {}
Meteor.methods({
getToken: function () {
var token;
do {
token = Random.id();
} while (clients[token]);
clients[token] = {
dependency: new Deps.Dependency(),
messages: [],
};
return token;
},
});
新客户端需要请求令牌并订阅数据流:
Meteor.startup(function () {
Meteor.call('getToken', function (error, myToken) {
// possibly use local storage to save the token for further use
if (!error) {
Meteor.subscribe('messages', myToken);
}
});
});
在服务器上,您需要定义自定义发布方法:
Meteor.publish('messages', function (token) {
var self = this;
if (!clients[token]) {
throw new Meteor.Error(403, 'Access deniend.');
}
send(token, 'hello my new client');
var handle = Deps.autorun(function () {
clients[token].dependency.depend();
while (clients[token].messages.length) {
self.added('messages', Random.id(), {
message: clients[token].messages.shift()
});
}
});
self.ready();
self.onStop(function () {
handle.stop();
});
});
并且send
函数可以定义如下:
var send = function (token, message) {
if (clients[token]) {
clients[token].messages.push(message);
clients[token].dependency.changed();
}
}
这是我将使用的方法。请检查它是否适合您。