在每个浏览器窗口中显示所有当前访问者光标的最佳方法是什么?
这是否可以实现,没有太多滞后?
这是我对meteor js的尝试:
http://meteorpad.com/pad/rCSsroc4G4gYQGkAY/Leaderboard(请注意名称,不能改变它吗?)
http://allofthecursors.meteor.com/
cursors.js:
Cursors = new Mongo.Collection("Cursors");
if (Meteor.isClient) {
Meteor.startup(function () {
if(!Session.get('cursorId')) {
// todo: not unique enough!
var cursorId = new Date();
Session.set('cursorId', cursorId);
Meteor.call('initCursor', cursorId);
}
});
Template.cursor.helpers({
cursor: function() {
return Cursors.findOne({ cursorId: Session.get('cursorId') });
},
cursors: function() {
return Cursors.find({ cursorId: { $ne: Session.get('cursorId') } });
}
});
Template.cursor.events({
"mousemove": function(event) {
var x = event.pageX,
y = event.pageY,
cursorId = Session.get('cursorId');
Meteor.call('updateCursor', cursorId, x, y);
}
});
}
if (Meteor.isServer) {
Meteor.methods({
'initCursor': function(cursorId) {
Cursors.insert({
cursorId: cursorId,
x: 0,
y: 0
});
},
'updateCursor': function(cursorId, x, y) {
Cursors.update(
{ cursorId: cursorId },
{ $set: { x: x, y: y }}
);
}
});
}
cursors.html
<head>
<title>cursors</title>
</head>
<body>
{{> cursor}}
</body>
<template name="cursor">
<div class="cursors-area">
{{#each cursors}}
<div class="cursor" style="top: {{y}}px; left: {{x}}px;"></div>
{{/each}}
<div class="my-cursor">
{{cursor.cursorId}}: {{cursor.x}}, {{cursor.y}}
</div>
</div>
</template>
cursors.css
html, body {
margin: 0;
padding: 0;
}
.cursors-area {
height: 100vh;
}
.cursor {
position: fixed;
width: 11px;
height: 17px;
background-image: url(cursor.png);
}
感谢evrybady的回应。这是更新版本。
添加了流包: $ meteor add lepozepo:streams
客户端集合仅用于访问被动功能。
cursors_2.js
Stream = new Meteor.Stream('public');
if( Meteor.isClient ) {
Cursors = new Mongo.Collection(null);
Template.cursor.events({
'mousemove': function(event) {
if (Meteor.status().connected) {
Stream.emit('p', {
_id: Meteor.connection._lastSessionId,
x: event.pageX,
y: event.pageY
});
}
}
});
Stream.on('p', function(p) {
// how can I change this?
if( Cursors.findOne(p._id) === undefined ) {
Cursors.insert({
_id: p._id,
x: p.x,
y: p.y
});
} else {
Cursors.update(p._id, {
$set: {
x: p.x,
y: p.y
}
}
);
}
});
function getCursors() {
return Cursors.find();
}
var throttledGetCursors = _.throttle(getCursors, 50);
Template.cursor.helpers({
cursors: throttledGetCursors
});
}
答案 0 :(得分:1)
基本上有两种方法可以解决这个问题。
<强>客户端强>
Template.body.events({
'mousemove': function(event) {
if (Meteor.status().connected) {
Cursors.update(Meteor.connection._lastSessionId, {
$set: {
x: event.pageX,
y: event.pageY
}
});
}
}
});
服务器强>
Meteor.onConnection(function(connection) {
Cursors.insert({
_id: connection.id,
x: 0,
y: 0
});
connection.onClose(function() {
Cursors.remove(connection.id);
});
});
除了避免使用会话变量之外,还使用会话ID为每个客户端提供唯一的游标ID,并在断开连接时将其从集合中删除。从安全角度来看,这也是首选,因为它允许您阻止用户更新不共享其连接ID的游标(通过允许/拒绝),以防万一。或者
lepozepo:streams
包(docs here)允许您更接近原始websocket进行通信,虽然它将涉及更多的管道,但将导致更少的延迟。 2015年12月伦敦DevShop对此进行了一些讨论,视频即将推出。如果有人可以为纯粹的服务器 - 客户端消息(独立于集合)编写集合,那将是很好的,但我认为目前不存在。另外,同意@sbking您应该使用Underscore(不限制)来更新更新。
答案 1 :(得分:0)
使用WebRTC进行此操作。谷歌吧。
基本上你将使用一些JavaScript将两个浏览器连接在一起,Meteor将发送握手,然后两个浏览器可以通话。从这里,你可以做各种数据密集型的东西,而不会炸毁Meteor或你的客户。 EZ。 PZ。