One-way Mirror¶
A one-way mirror is used in some physical lab experiments to allow unobtrusive observation of participants. Using the real-time capabilities of Meteor, this is actually fairly easy to set up on an existing app.
Creating a digital one-way mirror¶
In the worlds and assignment section, we explained how TurkServer is designed around multiple worlds that participants can be assigned to. This example explains how to build a one way mirror or view into the experiments you are running, so that you can observe what’s happening in real time. Although this may seem like a superfluous feature, in practice you’re likely to find it incredibly useful for qualitatively understanding what’s going on—even before getting to data analysis.
The following code is built around the partitioner API that
TurkServer users to divide a Meteor app into different ‘worlds’. Consider the
example in the partitioner docs, describing how to use the
same ChatMessages
collection to effectively create a collection of
separate chatrooms. To create a one-way mirror allowing you to see all
chatrooms simultaneously, you could do the following.
Set up a new publication on the server¶
First, set up a new publication on the server, allowing direct access to the data from any particular world.
Meteor.publish("oneWayMirror", function (worldId) {
return [
ChatMessages.direct.find({ _groupId: worldId }),
Meteor.users.direct.find({group: worldId}, { fields: { username: 1 } })
];
});
The above publication returns data about the chat messages and users, partitioned by a given world.
For those who are curious,_groupId
is the world identifier in the partitioner package. The.direct
syntax specifies to override the automatic partitioning or or ‘multiple worlds’ logic to directly query any particular world. The “magic” that happens with different groups in TurkServer is that the_groupId
field is inserted automatically depending on a particular user’s group membership.
Meteor.users
is the standard collection for Meteor’s accounts system, which is already defined. This pre-existing collection is partitioned differently from other collections that one creates (such asChatMessages
); the second argument is a field specifier so that the query returns just the username instead of other users fields such as the login token, which you would not want other users to see.
Create a view for the experimenter on the client¶
TurkServer uses Iron Router to control the display of templates on the client. You can use the API to add a new route for the experimenter to use the one-way mirror:
Router.map(function () {
this.route('expAdmin', {
path: 'exp/:groupId',
waitOn: function () {
return Meteor.subscribe("oneWayMirror", this.params.groupId);
},
data: function () {
return { groupId: this.params.groupId }
},
template: 'experiment',
});
});
For the details of the code above, take a look at the Iron Router
documentation. It is a pretty well-documented client-side routing
package for Meteor, and currently the most commonly used. For example,
specifying a path
of exp/:groupId
means that browsing to exp/foo
store
foo
to the groupId
parameter of the route params. The above function then
subscribes to the oneWayMirror
publication with this groupId
as well as
passing it as an argument to the template in the data
function. Check out the
Iron Router guide to see more examples of how to specify routes.
The above code allows the experimenter to visit https://<server>/exp/<id>
to
see what’s happening with a particular group of people. The user interface that
will be seen is defined by the experiment
template. Usually you can just use
the same interface that you have already built for participants, but for certain
instances it may be useful to design a particular experimenter view (see
examples below).
Hook up your mirror to the experimenter console¶
Since world identifiers are randomly generated by Meteor, it would be
inconvenient to have to type them in yourself. Fortunately, you can specify
the route for the one-way mirror in Meteor’s settings.json
to view worlds
automatically:
{
"public": {
"turkserver": {
"dataRoute": "expAdmin"
}
}
}
Under the Experiments view of the admin console, this will create a convenient button that you can click to watch ongoing or completed experiments (worlds) in real time.
Examples¶
Although the code for a one-way mirror is minimal, it may help to look at the following implementations for inspiration.
Crisis Mapping¶
This code accomplishes a pretty complex one-way mirror that allows real-time observation over a number of different collections, producing the (fast-forwarded) video above. However, the code is still minimal.