networked-aframe
Version:
A web framework for building multi-user virtual reality experiences.
86 lines (76 loc) • 3.55 kB
JavaScript
/* global AFRAME, NAF */
AFRAME.registerComponent('persistent-p2p', {
init: function() {
this.onConnected = this.onConnected.bind(this);
this.sendPersistentEntityCreated = this.sendPersistentEntityCreated.bind(this);
if (NAF.clientId) {
this.onConnected();
} else {
document.body.addEventListener('connected', this.onConnected, false);
}
},
onConnected: function() {
const receiveData = (_senderId, _dataType, data) => {
if (data.eventType === 'persistentEntityCreated') {
const el = document.createElement('a-entity');
this.el.sceneEl.appendChild(el);
el.setAttribute('networked', {
networkId: data.networkId,
template: data.template,
persistent: true,
owner: 'scene'
});
// If we receive a {persistent: true, isFirstSync: true} NAF `u` message before the
// persistentEntityCreated message, the NAF message is stored in
// NAF.entities._persistentFirstSyncs waiting the entity to be created.
// After creating the entity like we just did above, we need to call
// applyPersistentFirstSync to consume the received data to really
// initialize the networked component, otherwise it won't show.
NAF.utils.getNetworkedEntity(el).then((networkedEl) => {
networkedEl.components.networked.applyPersistentFirstSync();
});
}
}
NAF.connection.subscribeToDataChannel('events', receiveData);
// The persistentEntityCreated event is emitted by the spawner-persistent component.
// Broadcast a persistentEntityCreated message to everyone in the room.
document.body.addEventListener('persistentEntityCreated', this.sendPersistentEntityCreated, false);
// Note that when a participant leave the room, the other participants take ownership of the persistent entities of the left participant,
// see the code in the NetworkEntities.removeEntitiesOfClient function for details.
// When a new participant enter the room, send the persistentEntityCreated
// message for each persistent entity I own.
// Sending the networked data are done by NAF already with the same logic.
document.body.addEventListener('clientConnected', (evt) => {
const targetClientId = evt.detail.clientId;
for (const id in NAF.entities.entities) {
if (NAF.entities.entities[id]) {
const networkedComponent = NAF.entities.entities[id].components.networked;
const networkedData = networkedComponent.data;
if (networkedData.persistent && networkedData.owner && networkedComponent.isMine()) {
const data = {
eventType: 'persistentEntityCreated',
networkId: networkedData.networkId,
template: networkedData.template
};
NAF.connection.sendDataGuaranteed(targetClientId, 'events', data);
}
}
}
});
document.body.removeEventListener('connected', this.onConnected, false);
},
sendPersistentEntityCreated: function(evt) {
const el = evt.detail.el;
NAF.utils.getNetworkedEntity(el).then((networkedEl) => {
if (NAF.connection.isConnected()) {
const networkedData = networkedEl.components.networked.data;
const data = {
eventType: 'persistentEntityCreated',
networkId: networkedData.networkId,
template: networkedData.template
};
NAF.connection.broadcastDataGuaranteed('events', data);
}
});
}
});