Giter Site home page Giter Site logo

networked-aframe / networked-aframe Goto Github PK

View Code? Open in Web Editor NEW
1.1K 64.0 293.0 36.92 MB

A web framework for building multi-user virtual reality experiences.

Home Page: https://naf-examples.glitch.me

License: MIT License

JavaScript 99.96% Shell 0.04%
aframe webrtc virtual-reality webvr webxr game game-development socialvr multi-user-vr

networked-aframe's Introduction

Networked-Aframe

NPM version NPM downloads

Multi-user VR on the Web

A framework for writing multi-user VR apps in HTML and JS.

Built on top of A-Frame.


Features

  • Support for WebRTC and/or WebSocket connections.
  • Voice chat. Audio streaming to let your users talk in-app (WebRTC only).
  • Video chat. See video streams in-app.
  • Bandwidth sensitive. Only send network updates when things change.
  • Cross-platform. Works on all modern Desktop and Mobile browsers. Oculus Rift, Oculus Quest, HTC Vive and Google Cardboard.
  • Extendable. Sync any A-Frame component, including your own, without changing the component code at all.

Release notes

You can read the release notes to know what changed in the latest releases.

Getting Started

Remix on Glitch

Follow the NAF Getting Started tutorial to build your own example from scratch, including setting up a local server.

To run the examples on your own PC:

git clone https://github.com/networked-aframe/networked-aframe.git  # Clone the repository.
cd networked-aframe
npm install  # Install dependencies.
npm run dev  # Start the local development server.

With the server running, browse the examples at http://localhost:8080. Open another browser tab and point it to the same URL to see the other client.

For info on how to host your experience on the internet, see the NAF Hosting Guide.

Basic Example

<html>
  <head>
    <title>My Networked-Aframe Scene</title>
    <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.5.0/socket.io.slim.js"></script>
    <script src="/easyrtc/easyrtc.js"></script>
    <script src="https://unpkg.com/networked-aframe@^0.12.0/dist/networked-aframe.min.js"></script>
  </head>
  <body>
    <a-scene networked-scene>
      <a-assets>
        <template id="avatar-template">
          <a-sphere></a-sphere>
        </template>
      </a-assets>
      <a-entity id="player" networked="template:#avatar-template;attachTemplateToLocal:false;" camera wasd-controls look-controls>
      </a-entity>
    </a-scene>
  </body>
</html>

More Examples

Open in two tabs if nobody else is online, or remix the code examples yourself.

More complete examples:

Not updated to latest version:

Made something awesome with Networked-Aframe? Let us know and we'll include it here.

Documentation

Overview

Networked-Aframe works by syncing entities and their components to connected users. To connect to a room you need to add the networked-scene component to the a-scene element. For an entity to be synced, add the networked component to it. By default the position and rotation components are synced, but if you want to sync other components or child components you need to define a schema. For more advanced control over the network messages see the sections on Broadcasting Custom Messages and Options.

Scene component

Required on the A-Frame <a-scene> component.

<a-scene networked-scene="
  serverURL: /;
  app: <appId>;
  room: <roomName>;
  connectOnLoad: true;
  onConnect: onConnect;
  adapter: wseasyrtc;
  audio: false;
  video: false;
  debug: false;
">
  ...
</a-scene>
Property Description Default Value
serverURL Choose where the WebSocket / signalling server is located. /
app Unique app name. Spaces are not allowed. default
room Unique room name. Can be multiple per app. Spaces are not allowed. There can be multiple rooms per app and clients can only connect to clients in the same app & room. default
connectOnLoad Connect to the server as soon as the webpage loads. true
onConnect Function to be called when client has successfully connected to the server. onConnect
adapter The network service that you wish to use, see adapters. wseasyrtc
audio Turn on / off microphone audio streaming for your app. Only works if the chosen adapter supports it. false
video Turn on / off video streaming for your app. Only works if the chosen adapter supports it. false
debug Turn on / off Networked-Aframe debug logs. false

Connecting

By default, networked-scene will connect to your server automatically. To prevent this and instead have control over when to connect, set connectOnLoad to false in networked-scene. When you are ready to connect emit the connect event on the a-scene element.

AFRAME.scenes[0].emit('connect');

Disconnecting

To disconnect simply remove the networked-scene component from the a-scene element.

AFRAME.scenes[0].removeAttribute('networked-scene');

Completely removing a-scene from your page will also handle cleanly disconnecting.

Creating Networked Entities

<a-assets>
  <template id="my-template">
    <a-entity>
      <a-sphere color="#f00"></a-sphere>
    </a-entity>
  </template>
</a-assets>

<!-- Attach local template by default -->
<a-entity networked="template: #my-template">
</a-entity>

<!-- Do not attach local template -->
<a-entity networked="template:#my-template;attachTemplateToLocal:false">
</a-entity>

Create an instance of a template to be synced across clients. The position and rotation will be synced by default. The buffered-interpolation library is used to allow for less network updates while keeping smooth motion.

Templates must only have one root element. When attachTemplateToLocal is set to true, the attributes on this element will be copied to the local entity and the children will be appended to the local entity. Remotely instantiated entities will be a copy of the root element of the template with the networked component added to it.

Example attachTemplateToLocal=true

<a-entity wasd-controls networked="template:#my-template">
</a-entity>

<!-- Locally instantiated as: -->
<a-entity wasd-controls networked="template:#my-template">
  <a-sphere color="#f00"></a-sphere>
</a-entity>

<!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;">
  <a-sphere color="#f00"></a-sphere>
</a-entity>

Example attachTemplateToLocal=false

<a-entity wasd-controls networked="template:#my-template;attachTemplateToLocal:false;">
</a-entity>

<!-- No changes to local entity on instantiation -->

<!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;">
  <a-sphere color="#f00"></a-sphere>
</a-entity>
Property Description Default Value
template A css selector to a template tag stored in <a-assets> ''
attachTemplateToLocal Does not attach the template for the local user when set to false. This is useful when there is different behavior locally and remotely. true
persistent On remote creator (not owner) disconnect, attempts to take ownership of persistent entities rather than delete them false

Deleting Networked Entities

Currently only the creator of a network entity can delete it. To delete, simply delete the element from the HTML using regular DOM APIs and Networked-Aframe will handle the syncing automatically.

Syncing Custom Components

By default, the position and rotation components on the root entity are synced.

To sync other components and components of child entities you need to define a schema per template. Here's how to define and add a schema:

NAF.schemas.add({
  template: '#avatar-template',
  components: [
    'position',
    'rotation',
    'scale',
    {
      selector: '.hairs',
      component: 'show-child'
    },
    {
      selector: '.head',
      component: 'material',
      property: 'color'
    },
  ]
});

Components of the root entity can be defined with the name of the component. Components of child entities can be defined with an object with both the selector field, which uses a standard CSS selector to be used by document.querySelector, and the component field which specifies the name of the component. To only sync one property of a multi-property component, add the property field with the name of the property.

Once you've defined the schema then add it to the list of schemas by calling NAF.schemas.add(YOUR_SCHEMA).

Component data is retrieved by the A-Frame Component data property. During the network tick each component's data is checked against its previous synced value; if the data object has changed at all it will be synced across the network.

Syncing components optimization

For each component, you can define a requiresNetworkUpdate function that takes the current value and return true if the current value changed from the previous value. You can return false if current and previous value are close enough, to not send this change to other participants.

By default when you don't define it, it always use the defaultRequiresUpdate function (defined at the top of networked.js) which is using a generic deepEqual function to compare the current value with the previous value and use cachedData = AFRAME.utils.clone(newData); when both values are different to keep the previous value for the next comparison. AFRAME.utils.clone implementation is doing JSON.parse(JSON.stringify(obj)) that can be used with any type, but this may not be the best performance implementation for Vector3 type like position, rotation, scale.

Just so you know what this is doing:

> const v = new THREE.Vector3(1,2,3);
Vector3 {x: 1, y: 2, z: 3}
> JSON.parse(JSON.stringify(v))
{x: 1, y: 2, z: 3}

So this is creating a new object in memory each time the syncing process is done if the value changed, those objects are garbage collected at one point. Garbage collection in general can take 1ms or more if you have a heavy scene, a consequence could be that the browser drops some frames, so not having a consistent fps. You can use Chrome profiler to confirm this. This is barely noticeable with just your moving avatar, but it may be important for your use case if the user owns a lot of continuously moving objects.

Moreover with the current aframe wasd-controls implementation and how the position is smoothed, the player position is still changing below the millimeter precision 2s after the user stopped pressing a key, so sending a lot of NAF messages over the network for visually unnoticeable changes of position. NAF already includes position interpolation to smooth the position changes received, so sending all those position changes over the network is even redundant.

You can use a dedicated function to compare two Vector3 with a given precision to achieve better performance in term of sending less messages over the network and memory by avoiding creating new objects:

const vectorRequiresUpdate = epsilon => {
  return () => {
    let prev = null;

    return curr => {
      if (prev === null) {
        prev = new THREE.Vector3(curr.x, curr.y, curr.z);
        return true;
      } else if (!NAF.utils.almostEqualVec3(prev, curr, epsilon)) {
        prev.copy(curr);
        return true;
      }

      return false;
    };
  };
};

This function is actually defined in NAF.utils.vectorRequiresUpdate for you to use.

To use it in your networked schema for a position precision of 1 millimeter and rotation precision of 0.5 degree, use it like this:

{
  template: '#avatar-template',
  components: [
    {
      component: 'position',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)
    },
    {
      component: 'rotation',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)
    }
  ]
}

The default schema that sync position and rotation uses the above optimization since version 0.11.0.

Syncing nested templates - eg. hands

To sync nested templates setup your HTML nodes like so:

<a-entity id="player" networked="template:#player-template;attachTemplateToLocal:false;" wasd-controls>
  <a-entity camera look-controls networked="template:#head-template;attachTemplateToLocal:false;"></a-entity>
  <a-entity hand-controls="hand:left" networked="template:#left-hand-template"></a-entity>
  <a-entity hand-controls="hand:right" networked="template:#right-hand-template"></a-entity>
</a-entity>

In this example the head/camera, left and right hands of controllers will spawn their own templates which will be networked independently of the root player. Note: this is not related to hand tracking which is currently not supported. This parent-child relationship only works between one level, ie. a child entity's direct parent must have the networked component.

You need to define your left and right hand templates yourself to show hand models for the other users. Only the position and rotation will be synced to the other users. To sync the hand gesture, see the networked-hand-controls component below.

Tracked Controllers w/ Synced Gestures

This is a much simpler alternative to the above. NAF allows easily adding hand models visible to the others that show emulated gestures (not hand tracking) matching to which buttons are touched--so you can point and give a thumbs up or make a fist to other people in the room.

All you have to do is use the built in networked-hand-controls component, by adding these two entities as children of your camera rig:

<a-entity
  id="my-tracked-left-hand"
  networked-hand-controls="hand:left"
  networked="template:#left-hand-default-template"
></a-entity>
<a-entity
  id="my-tracked-right-hand"
  networked-hand-controls="hand:right"
  networked="template:#right-hand-default-template"
></a-entity

To see a working demo, check out the Glitch NAF Tracked Controllers Example.

The public schema properties you can set are:

Property Description Default Value Values
color Will be set as material color white
hand Specify if entity is for left or right hand left left, right
handModelStyle Available built-in models from A-Frame highPoly highPoly, lowPoly, toon, controller
customHandModelURL Optional custom hand model url

Note the 'controller' option--that will use a model of the controller itself, automatically set correctly according to your platform--it will also broadcast model-supported button mesh updates. (Unfortunately, there's currently a bug with the Quest 2 model button meshes, so that one doesn't show any updates.)

The networked-hand-controls is replacing completely hand-controls, don't use both. If you use the networked component as described above, you don't need to define the template and the networked schema for each hand. Default templates and networked schemas are already defined as follow:

<template id="left-hand-default-template">
  <a-entity networked-hand-controls="hand:left"></a-entity>
</template>
<template id="right-hand-default-template">
  <a-entity networked-hand-controls="hand:right"></a-entity>
</template>
NAF.schemas.add({
  template: '#left-hand-default-template',
  components: [
    {
      component: 'position',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)
    },
    {
      component: 'rotation',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)
    },
    'networked-hand-controls'
  ]
});
NAF.schemas.add({
  template: '#right-hand-default-template',
  components: [
    {
      component: 'position',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)
    },
    {
      component: 'rotation',
      requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)
    },
    'networked-hand-controls'
  ]
});

Sending Custom Messages

NAF.connection.subscribeToDataChannel(dataType, callback)
NAF.connection.unsubscribeToDataChannel(dataType)

NAF.connection.broadcastData(dataType, data)
NAF.connection.broadcastDataGuaranteed(dataType, data)

NAF.connection.sendData(clientId, dataType, data)
NAF.connection.sendDataGuaranteed(clientId, dataType, data)

Subscribe and unsubscribe callbacks to network messages specified by dataType. Broadcast data to all clients in your room with the broadcastData functions. To send only to a specific client, use the sendData functions instead.

Parameter Description
clientId ClientId to send this data to
dataType String to identify a network message. u (Update), um (UpdateMulti) and r (Remove) are reserved data types, don't use them please
callback Function to be called when message of type dataType is received. Parameters: function(senderId, dataType, data, targetObj) With the easyrtc adapter targetObj can be {targetRoom: 'roomId'} when broadcasting a message or {targetEasyrtcid: 'targetId'} when sending a message to a specific participant. With the janus adapter, senderId is always null and targetObj is more a source parameter and generally equals to "janus-event".
data Object to be sent to all other clients

Transfer Entity Ownership

The owner of an entity is responsible for syncing its component data. When a user wants to modify another user's entity they must first take ownership of that entity. The ownership transfer example and the toggle-ownership component show how to take ownership of an entity and update it.

NAF.utils.takeOwnership(entityEl)

Take ownership of an entity.

NAF.utils.isMine(entityEl)

Check if you own the specified entity.

Events

Events are fired when certain things happen in NAF. To subscribe to these events follow this pattern:

document.body.addEventListener('clientConnected', function (evt) {
  console.error('clientConnected event. clientId =', evt.detail.clientId);
});

Events need to be subscribed after the document.body element has been created. This could be achieved by waiting for the document.body onLoad method, or by using NAF's onConnect function. Use the NAF Events Demo as an example.

List of events:

Event Description Values
clientConnected Fired when another client connects to you evt.detail.clientId - ClientId of connecting client
clientDisconnected Fired when another client disconnects from you evt.detail.clientId - ClientId of disconnecting client
entityCreated Fired when a networked entity is created evt.detail.el - new entity
entityRemoved Fired when a networked entity is deleted evt.detail.networkId - networkId of deleted entity

The following events are fired on the networked component. See the toggle-ownership component for examples.

List of ownership transfer events:

Event Description Values
ownership-gained Fired when a networked entity's ownership is taken evt.detail.el - the entity whose ownership was gained
evt.detail.oldOwner - the clientId of the previous owner
ownership-lost Fired when a networked entity's ownership is lost evt.detail.el - the entity whose ownership was lost
evt.detail.newOwner - the clientId of the new owner
ownership-changed Fired when a networked entity's ownership is changed evt.detail.el - the entity whose ownership was lost
evt.detail.oldOwner - the clientId of the previous owner
evt.detail.newOwner - the clientId of the new owner

Adapters

NAF can be used with multiple network libraries and services. An adapter is a class which adds support for a library to NAF. If you're just hacking on a small project or proof of concept you'll probably be fine with the default configuration and you can skip this section. Considerations you should make when evaluating different adapters are:

  • How many concurrent users do you need to support in one room?
  • Do you want to host your own server? Or would a "serverless" solution like Firebase do the job?
  • Do you need audio (microphone) streaming?
  • Do you need custom server-side logic?
  • Do you want a WebSocket (client-server) network architecture or WebRTC (peer-to-peer)?

By default the wseasyrtc adapter is used, which does not support audio and uses a TCP connection. This is not ideal for production deployments however due to inherent connection issues with WebRTC we've set it as the default. To support audio via WebRTC be sure the server is using https and change the adapter to easyrtc (this uses UDP).

If you're interested in contributing to NAF a great opportunity is to add support for more adapters and send a pull request.

List of the supported adapters:

Adapter Description Supports Audio/Video WebSockets or WebRTC How to start
wseasyrtc DEFAULT - Uses the open-easyrtc library No WebSockets npm run dev
easyrtc Uses the open-easyrtc library Audio and Video (camera and screen share) WebRTC npm run dev
janus Uses the Janus WebRTC server and janus-plugin-sfu Audio and Video (camera OR screen share) WebRTC See naf-janus-adapter
socketio SocketIO implementation without external library (server supports room instancing) No WebSockets npm run dev-socketio
webrtc Native WebRTC implementation without external library (work in progress, currently no maintainer) Audio WebRTC npm run dev-socketio
Firebase Firebase for WebRTC signalling (currently no maintainer) No WebRTC See naf-firebase-adapter
uWS Implementation of uWebSockets (currently no maintainer) No WebSockets See naf-uws-adapter

WebRTC in the table means that component updates is using WebRTC Datachannels (UDP) instead of the WebSocket (TCP). You still have a WebSocket for the signaling part.

See also the document NAF adapters comparison.

Audio

After adding audio: true to the networked-scene component (and using an adapter that supports it) you will not hear any audio by default. Though the audio will be streaming, it will not be audible until an entity with a networked-audio-source is created. The audio from the owner of this entity will be emitted in 3D space from that entity's position. The networked-audio-source component must be added to an entity (or a child of an entity) with the networked component.

To quickly get started, try the Glitch NAF Audio Example.

To mute/unmute the microphone, you can use the following API (easyrtc and janus adapters):

NAF.connection.adapter.enableMicrophone(enabled)

where enabled is true or false.

Video

After adding video: true (not needed for the janus adapter) to the networked-scene component (and using an adapter that supports it) you will not see any video by default. Though the video will be streaming, it will not be visible until an entity using a mesh (<a-plane> for example) with a networked-video-source is created. The video from the owner of this entity will be visible in 3D space from that entity's position. The networked-video-source component must be added to an <a-plane> child entity of an entity with the networked component.

This currently applies only to the easyrtc and janus adapters that supports the getMediaStream(clientId, type="video") API.

See the Video Streaming example that shows the user camera without audio.

To disable/reenable the camera, you can use the following API (easyrtc adapter only):

NAF.connection.adapter.enableCamera(enabled)

where enabled is true or false.

With the easyrtc adapter, you can add an additional video track like a screen share with the addLocalMediaStream and removeLocalMediaStream API:

navigator.mediaDevices.getDisplayMedia().then((stream) => {
  NAF.connection.adapter.addLocalMediaStream(stream, "screen");
});
NAF.connection.adapter.removeLocalMediaStream("screen");

See the Multi Streams example that uses a second plane with networked-video-source="streamName: screen" to show the screen share to the other participants. Be sure to look at the comments at the end of the html file of this example for known issues.

Misc

NAF.connection.isConnected()

Returns true if a connection has been established to the signalling server.

NAF.connection.getConnectedClients()

Returns the list of currently connected clients.

Options

NAF.options.updateRate

Frequency the network component sync function is called, per second. 10-20 is normal for most Social VR applications. Default is 15.

NAF.options.useLerp

By default when an entity is created the buffered-interpolation library is used to smooth out position, rotation and scale network updates. Set this to false if you don't want this feature to be used on creation.

Offline usage

NAF already includes easyrtc thus running npm run dev will provide a fully working solution without accessing an external server. The examples though do rely on both AFrame and other dependencies that not packaged with NAF. Consequently one would have to first adapt AFrame to work offline then do the same for all additional components. This basically boils down to downloading the scripts used and their content, e.g assets like 3D models, fonts, etc. It is recommended to load the page while the network console open and identify what requests go outside of the host.

For VR you will also need https as browsers require it for immersive mode. Instructions are provided in the server/easyrtc-server.js file. Namely you will have to generate a key and certificate, add them to your local CA then load them via the express server provided by NAF. Make sure to configure that properly at the top of server/easyrtc-server.js and enable https itself further down via https.createServer as instructed. Once you connect to the NAF server in VR the browser will still complain that the certificate is unknown. You can click on advanced and proceed.

Stay in Touch

  • Join the A-Frame Slack and add the #networked-aframe channel
  • Follow changes on GitHub
  • Let us know if you've made something with Networked-Aframe. We'd love to see it!

Help and More Information

Folder Structure

  • / (root)
    • Licenses and package information
  • /dist/
    • Packaged source code for deployment
  • /server/
    • Server code
  • /examples/
    • Example experiences
  • /src/
    • Client source code
  • /tests/
    • Unit tests

Roadmap

Interested in contributing? Open an issue or send a pull request.

License

This program is free software and is distributed under an MIT License.

networked-aframe's People

Contributors

3datawill avatar ahmedrana3d avatar andybak avatar antoniohof avatar atrus6 avatar brianpeiris avatar bruce90j avatar dependabot[bot] avatar dirkk0 avatar djoksimo avatar esnosy avatar gfodor avatar haydenjameslee avatar hthetiot avatar infinitelee avatar johnshaughnessy avatar kylebakerio avatar machenmusik avatar milesmcbain avatar mqp avatar netpro2k avatar osresearch avatar protyze avatar robertlong avatar suresh-jbt avatar takahirox avatar utopiah avatar vincentfretin avatar wassx avatar zach-capalbo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

networked-aframe's Issues

Let application handle getting local MediaStream

Related to #18, while working on adding support for screen sharing and video I realized that there are going to be a ton of different options a developer may want to set (source, resolution, FPS, etc) which all just back out to the adapter making a getUserMedia call and then passing that MediaStream off to a PeerConnection

Rather than continuing to add options to networked-scene to handle all these different cases, we should just allow the developer to get a MediaStream however they like and then pass it to the adapter. This would also allow the developer to request additional permissions at a later time and have the adapter renegotiate the PeerConnection for them.

I am thinking something like NAF.connection.adapter.setLocalMediaStream(stream). If we want to keep the case of enabling audio "easy", we could have NAF call getUserMedia and setLocalMediaStream on the developers behalf as part of connecting if audio: true is passed. This also means we can probably ditch enableMicrophone(bool) as the developer can handle managing the MediaStream on their own however they like.

Not able to install in my system.

  • 0 info it worked if it ends with ok
  • 1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'dev' ]
  • 2 info using [email protected]
  • 3 info using [email protected]
  • 4 verbose run-script [ 'predev', 'dev', 'postdev' ]
  • 5 info lifecycle [email protected]~predev: [email protected]
  • 6 info lifecycle [email protected]~dev: [email protected]
  • 7 verbose lifecycle [email protected]~dev: unsafe-perm in lifecycle true
  • 8 verbose lifecycle [email protected]~dev: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/rajababu/rb/aframe/networked-aframe/node_modules/.bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Users/rajababu/PycharmProjects/google-cloud-sdk/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Users/rajababu/anaconda/bin
  • 9 verbose lifecycle [email protected]~dev: CWD: /Users/rajababu/rb/aframe/networked-aframe
  • 10 silly lifecycle [email protected]~dev: Args: [ '-c', 'npm run build && node ./server/server.js' ]
  • 11 silly lifecycle [email protected]~dev: Returned: code: 1 signal: null
  • 12 info lifecycle [email protected]~dev: Failed to exec dev script
  • 13 verbose stack Error: [email protected] dev: npm run build && node ./server/server.js
  • 13 verbose stack Exit status 1
  • 13 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:280:16)
  • 13 verbose stack at emitTwo (events.js:125:13)
  • 13 verbose stack at EventEmitter.emit (events.js:213:7)
  • 13 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
  • 13 verbose stack at emitTwo (events.js:125:13)
  • 13 verbose stack at ChildProcess.emit (events.js:213:7)
  • 13 verbose stack at maybeClose (internal/child_process.js:927:16)
  • 13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
  • 14 verbose pkgid [email protected]
  • 15 verbose cwd /Users/rajababu/rb/aframe/networked-aframe
  • 16 verbose Darwin 16.7.0
  • 17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "dev"
  • 18 verbose node v8.4.0
  • 19 verbose npm v5.4.1
  • 20 error code ELIFECYCLE
  • 21 error errno 1
  • 22 error [email protected] dev: npm run build && node ./server/server.js
  • 22 error Exit status 1
  • 23 error Failed at the [email protected] dev script.
  • 23 error This is probably not a problem with npm. There is likely additional logging output above.
  • 24 verbose exit [ 1, true ]

Use EasyRTC video?

Have you tested or found some issue also adding video in the mix?
I'm thinking about using the lib for audio+video conference with max. of 4 peers (maybe more if all peers are desktop with large bandwidth and can handle WebRTC full mesh load)

Jittery movement syncing

I noticed a strange lerping problem today. I realized that it was happening because my MSI laptop didn't have the power cord plugged in, which causes the GPU to be throttled. Regardless, I don't think that should cause this issue so it may be worth looking into more.

Here's a gif showing the jittery movement (the red avatar is the jittery one).

naf-glitch

I'm not sure if this is a problem with sending or receiving yet. I noticed the problem with both wseasyrtc and easyrtc adapters.

Basic-audio.html does not work on iOS

As pointed in the #2 (comment):
This is most likely due to webrtc not being supported on iOS.

After changing the basic-audio.html, line 41, to:
adapter: wseasyrtc;

The voice still not being transmitted from/to the iPhone.

Using wseasyrtc makes the iPhone see the other players, but no audio.
And using easyrtc, there is no audio and no players.

unable to send message when using easyrtc with audio

This does not happen always. But frequent enough to cause concern in a production environment. The error that shows up in the javascript console is:

attempt to send message without a valid connection to the server. The debugger shows that it is from: chrome://devtools/content/webconsole/src/utils/index.js. This is even when it is run in Firefox.

The only way forward seems to be to exit the scene and reload it. And it always works then.

Multiple calls to the server

The following is the scenario:

  1. aframe and networked-aframe running on NodeJS server.
  2. From a webpage (index.html) I open an <iframe> with a url that loads an aframe scene.

Here is the observation:
a. When using ver 0.4.0 the url is called once (i have put a log on the nodejs server).
b. But when using ver 0.5.0 or 0.5.1 or 0.5.2, the same url is called several time.

For example, if the url is: .../walkthru?guest=rr, the following is the log (I disabled debug on server because the log was very large)

/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
roomCreate fired! Trying to create: walkthru
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr
/walkthru?guest=rr

This happens only when using a networked scene. I tried with a normal aframe scene and the url is called only once.

With easyrtc debug, the following shows up:

debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Room [default] Running func 'connectionRoomObj.emitRoomDataDelta'
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Room [default] Running func 'connectionRoomObj.generateRoomDataDelta'
debug   - EasyRTC: Running func 'onDisconnect'
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Running func 'onRoomLeave' with rooms [default]
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Leave room [default]
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Room [default] Running func 'connectionRoomObj.emitRoomDataDelta'
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Room [default] Running func 'connectionRoomObj.generateRoomDataDelta'
debug   - EasyRTC: [default][5lTkXP9Osf5k6JsQ] Disconnected
/walkthru?guest=rr
/walkthru?guest=rr
debug   - EasyRTC: [Q3fu8abAZcP2uVkS][JkaoPVXGMYI_m199AAAB] Socket connected
debug   - EasyRTC: Emitting event 'connection'
debug   - EasyRTC: Running func 'onConnection'
/walkthru?guest=rr
/walkthru?guest=rr
debug   - EasyRTC: [Q3fu8abAZcP2uVkS] Running func 'onEasyrtcAuth'
debug   - EasyRTC: Emitting Authenticate
roomCreate fired! Trying to create: walkthru
debug   - EasyRTC: [default][Q3fu8abAZcP2uVkS] Room [walkthru] Running func 'onRoomCreate'
debug   - EasyRTC: Creating room: 'walkthru' with options: {}
debug   - EasyRTC: [default][Q3fu8abAZcP2uVkS] Running func 'onRoomJoin'
debug   - EasyRTC: [default][Q3fu8abAZcP2uVkS] Room [walkthru] Running func 'connectionRoomObj.emitRoomDataDelta'
debug   - EasyRTC: [default][Q3fu8abAZcP2uVkS] Room [walkthru] Running func 'connectionRoomObj.generateRoomDataDelta'
/walkthru?guest=rr
debug   - EasyRTC: [default][Q3fu8abAZcP2uVkS] Running func 'onSendToken'
/walkthru?guest=rr
/walkthru?guest=rr

easyrtc: enable audio receive even if no getMediaStream supported

I suggest setting this.easyrtc.enableAudioReceive(true); as peers should always receive audio, regardless of them having access to mic or a supported browser.

This change includes setting the this.easyrtc.setStreamAcceptor(this._storeAudioStream.bind(this));
outside the _connectWithAudio function, as it must be set even if you didnt connect with audio: true.

System cannot find the path specified?

Hiya!

When trying to install it on my Windows PC, it seems to fail with the error "System cannot find the path specified". It seems like maybe it's a WebRTC issue? I've updated node and npm to the latest versions but it's still not happy!

It fails on this command - npm install && npm run easyrtc-install

The log looks like so:

0 info it worked if it ends with ok
1 verbose cli [ 'D:\\Programs\\nodejs\\node.exe',
1 verbose cli   'D:\\Programs\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'run',
1 verbose cli   'easyrtc-install' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'preeasyrtc-install',
4 verbose run-script   'easyrtc-install',
4 verbose run-script   'posteasyrtc-install' ]
5 info lifecycle [email protected]~preeasyrtc-install: [email protected]
6 silly lifecycle [email protected]~preeasyrtc-install: no script for preeasyrtc-install, continuing
7 info lifecycle [email protected]~easyrtc-install: [email protected]
8 verbose lifecycle [email protected]~easyrtc-install: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~easyrtc-install: PATH: D:\Programs\nodejs\node_modules\npm\bin\node-gyp-bin;D:\lab\networked-aframe\node_modules\.bin;C:\Users\Admin\bin;D:\Programs\Git\mingw64\bin;D:\Programs\Git\usr\local\bin;D:\Programs\Git\usr\bin;D:\Programs\Git\usr\bin;D:\Programs\Git\mingw64\bin;D:\Programs\Git\usr\bin;C:\Users\Admin\bin;C:\Program Files\Oculus\Support\oculus-runtime;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\WiFi\bin;C:\Program Files\Common Files\Intel\WirelessCommon;C:\Program Files (x86)\GtkSharp\2.12\bin;D:\Programs\Git\cmd;D:\Programs\PuTTY;D:\Programs\Android\sdk\platform-tools;D:\Programs\nodejs;C:\Users\Admin\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Intel\WiFi\bin;C:\Program Files\Common Files\Intel\WirelessCommon;C:\Users\Admin\AppData\Roaming\npm;D:\Programs\Git\usr\bin\vendor_perl;D:\Programs\Git\usr\bin\core_perl
10 verbose lifecycle [email protected]~easyrtc-install: CWD: D:\lab\networked-aframe
11 silly lifecycle [email protected]~easyrtc-install: Args: [ '/d /s /c',
11 silly lifecycle   'cd ./node_modules/easyrtc; npm install; cd ../../server; npm install; cd ../' ]
12 silly lifecycle [email protected]~easyrtc-install: Returned: code: 1  signal: null
13 info lifecycle [email protected]~easyrtc-install: Failed to exec easyrtc-install script
14 verbose stack Error: [email protected] easyrtc-install: `cd ./node_modules/easyrtc; npm install; cd ../../server; npm install; cd ../`
14 verbose stack Exit status 1
14 verbose stack     at EventEmitter.<anonymous> (D:\Programs\nodejs\node_modules\npm\lib\utils\lifecycle.js:255:16)
14 verbose stack     at emitTwo (events.js:106:13)
14 verbose stack     at EventEmitter.emit (events.js:191:7)
14 verbose stack     at ChildProcess.<anonymous> (D:\Programs\nodejs\node_modules\npm\lib\utils\spawn.js:40:14)
14 verbose stack     at emitTwo (events.js:106:13)
14 verbose stack     at ChildProcess.emit (events.js:191:7)
14 verbose stack     at maybeClose (internal/child_process.js:877:16)
14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid [email protected]
16 verbose cwd D:\lab\networked-aframe
17 error Windows_NT 10.0.14393
18 error argv "D:\\Programs\\nodejs\\node.exe" "D:\\Programs\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "easyrtc-install"
19 error node v6.10.0
20 error npm  v3.10.10
21 error code ELIFECYCLE
22 error [email protected] easyrtc-install: `cd ./node_modules/easyrtc; npm install; cd ../../server; npm install; cd ../`
22 error Exit status 1
23 error Failed at the [email protected] easyrtc-install script 'cd ./node_modules/easyrtc; npm install; cd ../../server; npm install; cd ../'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the networked-aframe package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error     cd ./node_modules/easyrtc; npm install; cd ../../server; npm install; cd ../
23 error You can get information on how to open an issue for this project with:
23 error     npm bugs networked-aframe
23 error Or if that isn't available, you can get their info via:
23 error     npm owner ls networked-aframe
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

view sync

May I ask a way to sync view? The two functions which we plan to implement:

  1. One room admin can control to make all other participants following admin's view sync.
  2. The room admin can see one participant's view sync to monitor.
    Thanks!

updating synced objects using third party components

Hi. Your project is awesome and i can't believe all the different stuff you can do with it and the different options it opens up. I wanted to ask if it is possible to continuously update custom entities that are synced using third party components like super-hands or click-drag. I've been trying for a while but can't seem to get the server to update the positions and rotations for the second viewer. Would ownership transfer help with that?

Position synchronization mystery glitch

Description:

Hi! I am using A-Frame and networked-aframe to hold VR office meetings with my colleagues, and we expect to see each other's avatars in the same relative positions across instances.

However, when we first connect to the office, the positions do not at first appear synched.
After entering the inspector, and then clicking 'Back to scene', however, then the avatars are mysteriously synched. Thanks @haydenjameslee for discovering this workaround.

Steps to Reproduce:

  1. Mute your computer's audio
  2. Visit https://elevr-office-net.glitch.me in two browser tabs
  3. Click 'Allow' (optional)
  4. In one tab, move the avatar/camera to one corner of the room
  5. In another tab, move the avatar/camera to another corner of the room
  6. In each tab, you should NOT see the opposite avatar where you think it should be
  7. Now, in both tabs, enter the inspector with ctrl+alt+i and then click 'Back to scene'
  8. Repeat steps 4 and 5
  9. This time, in each tab, you should see the opposite avatar where you think it should be

404 No found on line 2902

Hi,
Ive just updated to the latest version.
Great job with the ownership transfer and reconnect features!

My project is connecting fine, but this line is constantly giving 404 error:
function 'updateTimeOffset'
line 2902
return fetch(document.location.href, { method: "HEAD", cache: "no-cache" }).then(function (res) {

I'm using localhost, maybe its that?

Thank you

In networked-aframe-audio, avatars aren't visible until microphone permission is granted

When first entering a new host serving the audio demo, the avatar isn't visible. The last message in the browser console is "Networked-Aframe Connecting..."
When allowing the host access to the microphone, the message "Networked-Aframe Client ID: MXSscnIe..." appears and the avatar becomes visible.

I suggest to make the avatars visible immediately, even if the user did not allow mic access, to provide users an interesting experience as soon as they enter the demo page.

Used Chrome on OS X and Chrome on Win7, networked-aframe-audio.glitch.me currently using networked-aframe@^0.4.0.

Avatar vanishes on webrtcAudio flag setting to true

Hello,

I have created a networked aframe room with avatars for each player. The scene is as follows:

  <html>
   
   <head>
     <script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
     <script src="easyrtc/easyrtc.js"></script>
     <script src="https://unpkg.com/networked-aframe/dist/networked-aframe.min.js"></script>
     <script src="https://unpkg.com/aframe-room-component/dist/aframe-room-component.min.js"></script>
     <script>
       AFRAME.registerComponent('chair-listener', {
         init: function() {
           this.el.addEventListener('click', function(evt) {
             var cam = document.getElementById("cam");
             var chairpos = this.getAttribute("position");
             var campos = cam.getAttribute("position");
             campos.x = -3 + chairpos.x + 1.5;
             campos.y = 1;
             campos.z = -5 + chairpos.z;
             var camrot = cam.getAttribute("rotation");
             camrot.x = 0;
             camrot.y = 0;
             camrot.z = 0;
             var look = cam.getAttribute("look-controls");
             look.enabled = false;
             cam.setAttribute('look-controls', look);
             cam.setAttribute("position", campos);
             cam.setAttribute("userHeight", 1.4);
             look.enabled = true;
             cam.setAttribute('look-controls', look);
             console.log('hello');
           });
         }
       });
     </script>
     <script>
       // Define custom schema for syncing avatar color, set by random-color
       var avatarSchema = {
         template: '#avatar-template',
         components: [
           'position',
           'rotation',
           {
             selector: '.head',
             component: 'material'
           }
         ]
       };
       NAF.schemas.add(avatarSchema);
     </script>
   </head>
   
   <body>
     <a-scene networked-scene="app: myApp; room: room1; webrtc:true; webrtcAudio:false; debug: true;">
       <a-assets>
         <a-asset-item id="chair" src="chair.glb"></a-asset-item>
         <script id="avatar-template" type="text/html">
           <a-entity class="avatar">
             <a-sphere class="head" scale="0.1 0.1 0.1" color="red"></a-sphere>
           </a-entity>
         </script>
       </a-assets>
       <a-entity id="cam" networked="template:#avatar-template;showLocalTemplate:false;" camera="userHeight:1.6" wasd-controls look-controls>
         <a-entity cursor="fuse: true; fuseTimeout: 500" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat">
         </a-entity>
       </a-entity>
       <a-sky color="#ECECEC"></a-sky>
       <rw-room position="-3 0 -5" material="color:#787">
         <rw-floor material="color:red"></rw-floor>
         <rw-ceiling material="color:blue"></rw-ceiling>
         <rw-wall position="6 0 0" material="color:yellow"></rw-wall>
         <rw-wall position="6 0 6" material="color:green"></rw-wall>
         <rw-wall position="0 0 6" material="color:brown"></rw-wall>
         <rw-wall position="0 0 0" material="color:pink">
         </rw-wall>
         <a-entity chair-listener gltf-model="#chair" position="0.5 0 3" scale="0.5 0.5 0.5"></a-entity>
         <a-entity chair-listener gltf-model="#chair" position="3 0 3" scale="0.5 0.5 0.5"></a-entity>
       </rw-room>
     </a-scene>
   </body>
   
   </html>

Everything works fine till I enabled the webrtcAudio to true in the networked-scene attributes. After which the avatar (a red sphere) vanishes. Setting it back to false shows it. The additional information to note is that the page is being updated using NodeJS server.

I need the avatar and the need to have the users talk over VR.

Thanks for any help.

Raj

easyrtc: connection error causes crash

Hello,

I thought of recording a crash caused by easyrtc. It occurred when the networked-scene was being loaded. I am reproducing the error below.

EasyRTC: [default][pwob0IPhU3GLevUK] Running func 'onGetIceConfig'
/Users/rajnikantrao/Documents/GitHub/hudddle/node/node_modules/easyrtc/lib/easyrtc_public_obj.js:1668
            for (var fieldName in e.app[appName].connection[easyrtcid].field) {
                                                                       ^

TypeError: Cannot read property 'field' of undefined
    at Object.connectionObj.getFields (/Users/rajnikantrao/Documents/GitHub/hudddle/node/node_modules/easyrtc/lib/easyrtc_public_obj.js:1668:72)
    at /Users/rajnikantrao/Documents/GitHub/hudddle/node/node_modules/easyrtc/lib/easyrtc_default_event_listeners.js:1079:27
    at fn (/Users/rajnikantrao/Documents/GitHub/hudddle/node/node_modules/async/lib/async.js:582:34)
    at Immediate.<anonymous> (/Users/rajnikantrao/Documents/GitHub/hudddle/node/node_modules/async/lib/async.js:498:34)
    at runCallback (timers.js:773:18)
    at tryOnImmediate (timers.js:734:5)
    at processImmediate [as _immediateCallback] (timers.js:711:5)

This is the first time I am facing this error. Not sure if it is related to the earlier issue (#77) reported a few days back.

Getting Started tutorial missing build.js

I was following the Getting Started tutorial and I have run into a problem trying to reproduce your output for basic.html. I do not see any avatars and I see the following errors in my javascript console in my browser:

  • Failed to load resource: the server responded with a status of 404 (Not Found) build.js
  • Uncaught ReferenceError: NAF is not defined at basic.html:16

I'm a total node noob but it I think the problem here is that the tutorial assumes I am working from the networked-aframe dev environment, even though it told me to simply create a folder and install the npm dependencies. So for the tutorial to work build.js needs to be replaced with a link to node_modules/networked-aframe/dist/networked-aframe.js?

I tried this but the only way I could get it to work is if I copied networked-aframe.js over to ./server/static/.

Please let me know if I have missed something elementary.

Entities sometimes get instantiated multiple times

Still digging into the specifics but wanted to get this issue out there in case other people are seeing this and have more info. Sometimes when joining a room with multiple users an entity gets instantiated multiple times. This seems to only happen with nested entities and looks to be related to the child cache getting the same entity added multiple times.

Added some debug logging to createAndAppendChildren and in the failure case you can see the same child added to the cache many times. Still not fully clear on how so many were added since there were only a small handful of clients connected at the time. Perhaps there are multiple broadcasts per connection.

Spawning children 
[…]
0: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
1: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
2: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
3: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
4: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
5: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
6: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
7: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
8: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
9: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
10: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
11: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
12: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
13: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
14: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
15: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
16: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
17: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
18: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
19: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
20: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
21: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
22: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
23: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
24: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
25: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
26: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
27: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
28: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
29: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
30: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
31: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
32: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
33: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
34: Object { 0: 0, networkId: "1h08u8p", owner: "IF2XkyCWMlm55Tog", … }
35: Object { 0: 0, networkId: "2ukhn81", owner: "IF2XkyCWMlm55Tog", … }
36: Object { 0: 0, networkId: "dut8cjg", owner: "IF2XkyCWMlm55Tog", … }
length: 37
__proto__: Array []

My best guess at what is happening is that since syncAll is done as a broadcast, and happens every time a datachannel is opened, there are cases where the timing works out such that you get multiple instantiation packets for a given child before instantiating its parent, thus adding it to the childCache multiple times, and then instantiating it multiple times.

I think there are a few things that should be fixed here:

  1. On opening a datachannel it should probably only send sync packets to the 1 user rather than broadcasting. Also not 100% clear on if this is already the case, but it should only do this once per logical connection (not for example once for the websocket connection and once for the webrtc datachannel)
  2. ChildCache should avoid storing the same entity multiple times. Since the data messages are not immutable I don't think a Set wold work, so likely it should just store them in a Map by their network id
  3. ChildCache and NetworkEntities should log warnings when this does happen so these sorts of bugs are easier to spot in the future.

Already taking a look at these fixes but just wanted to give a heads up.

Error deploying to Heroku

Hello!

I am very excited to try some networked-aframe projects with my team at elevr.com. We all have Google Pixel/Daydream devices.

I tested networked-aframe locally and it ran fine.

I then tried deploying to Heroku and ran into this error:

npm ERR! Tell the author that this fails on your system:
npm ERR!     watchify src/index.js -o server/static/build.js -v

The logs also say this at some point:

sh: 1: watchify: not found

I changed the package.json to match my node and npm local versions.
I am not sure if it has to do with the npm run easyrtc-install step that perhaps Heroku is never running. I tried to figure out how to have Heroku run that line automatically after npm install but wasn't able to make it work.

Please let me know if you have any tips, thank you!

easyrtc with audio doesnt work consistantly in Chrome

I am using the basic example from the tutorial with adapter changed to easyrtc and audio turned on

<a-scene networked-scene=" room: dev; debug: true; adapter: easyrtc; audio: true; ">

When hosting the server locally and testing in Chrome (v61.0.3163.100 64bit) a new tab joining an existing room will not see the existing occupants of the room, but the existing tabs will see the new comers. Audio is never present

Works as expected consistently in Firefox

Error on disconnect

Error happens on a disconnecting client. He never disconnects.
Other still detect him.
Even so, he still can reconnect or connect to other rooms with no problems.

value: function removeEntity(id) {
	      if (this.hasEntity(id)) {
	        var entity = this.entities[id];
	        delete this.entities[id];
	        **entity.parentNode.removeChild(entity);**
	        return entity;
	      } else {
	        return null;
	      }
	    }

Error:


networked-aframe.js?3eb0:2213 Uncaught TypeError: Cannot read property 'removeChild' of null
    at NetworkEntities.removeEntity (networked-aframe.js?3eb0:2213)
    at NetworkEntities.removeRemoteEntities (networked-aframe.js?3eb0:2240)
    at NetworkConnection.disconnect (networked-aframe.js?3eb0:2534)
    at NewComponent.remove (networked-aframe.js?3eb0:3027)
    at HTMLElement.value (aframe-master.js?e049:74171)
    at HTMLElement.value (aframe-master.js?e049:73815)
    at HTMLElement.wrappedMethod (aframe-master.js?e049:75134)
    at Object.removeChild (vue.esm.js?65d7:5235)
    at removeNode (vue.esm.js?65d7:5407)
    at remove (vue.esm.js?65d7:5396)

Clients Not Visible in WebVR on Samsung Internet

Using the Galaxy S8 on Google Chrome I can view other clients. But when using Samsung WebVR, no other clients are visible and the server doesn't even detect me connecting. WebRTC is set to false.

is there a raw three.js support

it could be useful, thus application in aframe and in three.js could communicate together

I think it makes sense because is a network library

Master & slave

Is there a way to create a master control for " admin " and when he trigger action it will change everyone's view?

Questions to use it in Augmented Reality

I love what you did, the easyness of it is so nice!

i would love to use that in augmented reality (with ar.js) but for that i need to change the usual behavior a bit, so i have 2 questions :)

  1. i would like to get the avatar, not attached to the camera, but somewhere above the marker. Where should i look to see how to change avatar position.
  2. i would like to move the avatar according to controls on a phone, so some kind of touchscreen joystick. Where should i look to be able to controls the position of the avatar from javascript ?

Thanks :)

how many concurrent users support?

Is there any clue shows how many concurrent users to support in one room? If we have 100 users in one room, what should we need to pay attention? Thanks.

example for sync besides avatar sync

Maybe I'm just too bad at js, but i tried this since some time now:
run a networked scene on a local server. avatar sync example is running great.
now if i add any other object to the scene (onkeydown or explicit html), it should appear for each other user, which it does
but: the readme states:

By default, the position and rotation components on the root entity are synced.

however, if i move the object either by animation or click-drag component, the object does not move for the other user.
i tried with template(analog to avatar), which supposedly isnt needed, i searched for other examples but all of them rely on firebase or so, which atm i dont want to use.
someone mentioned on twitter that its not easy to sync other objects, but i cannot find this any more and the discussion was moved to a moz dev forum...
maybe i'm missing something, any pointers appreciated

Networked A-Frame Doesn't Connect Unless I Refresh the Page

I'm running into this issue on both Firefox and Chrome. My scene will say that "Networked AFrame is connecting....." but won't then connect and give me a clientID. As soon as I refresh the page, it connects and give me the clientID. Has anyone else run into this issue?

AWS Tutorial

Hi i'm trying to follow the tutorial and i want to create a server on AWS on ubunto or centos but i want to know what i need to do before or some where i can find info about this thanks a lot

Port ranges for WebRTC

I've been playing around with getting the server running on an Ubuntu 16.04 VPS and am using iptables to manage firewalling. Just wondering what port ranges I should open up as it doesn't seem to want to allow connections from the client -> server if only ports 80, 443 and 8080 are open. I assume it's a problem with the STUN/TURN connection from the server to Google's servers. Do I just need to leave the higher ranges open? Is there any point restricting ports if this is the case?

Allow changing of server port number

This is more of a feature request — it'd be great to be able to change the port number that it runs on. e.g. rather than localhost:8080, to override it via the npm command to run on 5000?

Not sure if that would mess anything else up in the app, but it could be handy for those running a bunch of Node servers at once.

Issue running example locally

I'm getting the following error in the browser console when running the example locally using npm start then access it at http://MY_LOCAL_IP_ADDRESS:8080/basic.html:

Chrome:

build.js:2539 NOVIABLEICE No usable STUN/TURN path
(anonymous) @ build.js:2539

Firefox:

RTCIceServer.url is deprecated! Use urls instead. easyrtc.js:3587
onaddstream is deprecated! Use peerConnection.ontrack instead.  easyrtc.js:6356
RTCIceServer.url is deprecated! Use urls instead. easyrtc.js:3587
onaddstream is deprecated! Use peerConnection.ontrack instead.  easyrtc.js:6356
ICE failed, see about:webrtc for more details

Seems like easyrtc can't connect to the google stun servers correctly. Do you know what could be causing this? I'm running the browser on the same machine as the server.

It happens in the latest production version of Firefox and Chrome.

inconsistent creation of remote entity

Often remote entities are not getting created, perhaps one in ten times. The following is the scenario:

Environment is:
a. Aframe 0.7.0
b. NAF 0.5.1
c. adapter: easyrtc with audio

  1. Browser 1 enters NAF scene.
  2. Browser 2 enters NAF scene.
  3. Browser 2 gets remote client. Browser 1 may not get remote client.
  4. Browser 3 enters NAF scene.
  5. Browser 3 could get both remote clients. Browser 2 may get third remote entity. Even Browser 1 may get remote entity.

Request is: Can we have a method in NAF to refresh remote clients which would check the number of remote clients to be created and if not available in DOM would create them.

Like in the example above, since remote client 2 was not created in Browser 1, a refresh should detect it and recreate. Something like that. And the logic on whether to call such a method can stem from comparing easyrtc.getRoomOccupantsAsArray with the number of remote entities created.

How to get all connected players list

Hello,
I'm trying to get a list/array of all players ( player +naf-xxxxxx entities)
I found a list in NAF.entities.entities, but I'm unable to get them when i try to log it in the console, for I only get one reference.

Is there a method i missed, or does it need to be implemented ?

Audio not working in latest master

@netpro2k I tested the the positional audio PR in, merged it, then merged @robertlong's adapter registration PR. The positional audio seems not to be working, however I can't currently test it because my PC is acting up and no WebRTC audio samples are working at all. Could you check to make sure its working?

instructions for noobs

can you give instructions on how to deploy this on the web. on my server or heroku or something?

lerping in networked.js no longer correct after ownership transfer feature

attachLerp() is called in networked.js is only called if wasCreatedByNetwork is true, however because they can change ownership now this is not really a valid check anymore. attachLerp() should probably always be called, however the lerping should only be active if the component is not currently owned by the local player.

Mobile Clients not visible

Potentially when using HTTPS for signallingURL.

Desktop clients show:
Successfully started datachannel to Ao5IrnsQKoP2niV5
Opened data channel from Ao5IrnsQKoP2niV5
...
Closed data channel from Ao5IrnsQKoP2niV5

Mobile clients show only:
Closed data channel from Ao5IrnsQKoP2niV5

Idea: Merge wsEasyRTC adapter with EasyRTC adapter and add webrtc bool to networked-scene

Any WebSocket-only adapter can theoretically do WebRTC without much modification. Once there is a WebSocket connection all the signaling messages can transfer across it and then use WebRTCPeer.js like the naf-firebase-adapter to implement WebRTC.

I'm proposing we add another field to the networked-scene schema that allows you to toggle between WebSockets and WebRTC, thus halving the number of adapters we need and making it easier to test different architectures very quickly.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.