aframeaframe-networked

a-frame networked - how to match an avatar with a broadcasting client?


I'm using aframe-networked, and I'm sending some custom data between the users:

// sender
NAF.connection.broadcastDataGuaranteed(dataType, data)
// all recipients listen
NAF.connection.subscribeToDataChannel(dataType, (senderId, type, data, target) => {})

but I'm having trouble determining which avatar entity is corresponding to the broadcasting client. How the receivers know which player is the sender from the callback?


Solution

  • One way would be by using aframe-networked events, and keeping all connected users in a dictionary. The creatorID, ownerId and networkId are all kept in the networked component - so all You need is to grab them once the avatar is created:

    const usersMap = {};
    
    // Fired when a networked entity is created 
    document.body.addEventListener("entityCreated", function(evt) {
      const networkedComponent = evt.detail.el.getAttribute("networked");
      usersMap[networkedComponent.creator] = {
        networkId: networkedComponent.networkId,
        el: evt.detail.el
      };
    });
    
    // Fired when another client disconnects from you   
    document.body.addEventListener("clientDisconnected", function(evt) {
      if (usersMap[evt.detail.clientId]) delete usersMap[evt.detail.clientId];
    });
    

    Now, each time You get a callback from a broadcasted message (via NAF.connection.subscribeToDataChannel(dataType, callback)) You can easily track the entity belonging to the sender:

    // change the senders color to blue
    NAF.connection.subscribeToDataChannel("data", (sender, type, data, target) => {
      usersMap[sender].el.setAttribute("color", "blue");
    })
    

    You can see it working in this glitch. If any user presses "excuse me" the rest should see an exclamation mark above his head.


    If You're broadcasting data in another way (like another socket.io connection), You can pass Your own clientID (player.getAttribute("networked").creator) in the message, so the above stays the same,

    or you can pass the networkId, so the receiver can do a single query:

     let senderEntity = document.getElementById("naf-" + networkId)