Skip to content Skip to sidebar Skip to footer

JS SSE: Cannot Access Event.data Outside Of OnMsg Callback Function?

I am using three.js to visualize accelerometer data in real-time and in 3D on the browser. I am using server-sent-event to transfer data from the remote server to the client side.

Solution 1:

We will need to have sunMesh initialized either out of the scope of your main method or in the global scope to later access it.

Know that sunMesh would have to be initialized in your main method before you can access its position, so you might create a race condition if you don't do so synchronously (i.e. loading a model).

let sunMesh;

function main() {
  sunMesh = new THREE.Mesh(...)
}

function onMsg(event) {
  const sensorValue = event.data;
  sunMesh.position.x = sensorValue;
}

// or, in the global scope (I'd try to avoid this)

function main() {
  window.sunMesh = new THREE.Mesh(...)
}

function onMsg(event) {
  const sensorValue = event.data;
  window.sunMesh.position.x = sensorValue;
}

Edit: As your message events are asynchronous, you would have to render inside of your animation loop or inside of the onMsg function in order to render updates (you would do the same with camera, scene, and renderer references as above).

let sunMesh;

function main() {

  const canvas = document.querySelector('#canvas');
  const renderer = new THREE.WebGLRenderer({ canvas });
  var context = canvas.getContext("2d");

  const fov = 70;
  const aspect = 2;
  const near = 20;
  const far = 500;
  const color = 0xFFFFFF;
  const intensity = 1;
  const size = 10;
  const divisions = 10;
  const objects = [];
  const radius = 3;
  const widthSegments = 3;
  const heightSegments = 3;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  const sphereGeometry = new THREE.BoxGeometry(radius, widthSegments, heightSegments);
  const sunMaterial = new THREE.MeshBasicMaterial({ color: "green", wireframe: false });
  sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial)
  const light = new THREE.PointLight(color, intensity);
  // const gridHelper = new THREE.GridHelper(200000, 10000);

  camera.position.z = 0;
  camera.position.x = 100;
  camera.up.set(0, 0, 1);
  camera.lookAt(0, 0, 0);   

  const scene = new THREE.Scene();
  {
    const color = 0x00afaf;
    const intensity = 10;
    const light = new THREE.PointLight(color, intensity);
    scene.add(light);
    // gridHelper.geometry.rotateY(Math.PI / 2);
    // scene.add(gridHelper);
    // scene.add(light);
  }
  function resizeRendererToDisplaySize() {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

function resizeToClient() {
  const needResize = resizeRendererToDisplaySize()
  if (needResize) {
    const canvas = renderer.domElement;
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }
}

  var cubeAxis = new THREE.AxesHelper(10);
  sunMesh.add(cubeAxis);

  sunMesh.scale.set(5, 5, 5)
  scene.add(sunMesh);
  scene.background = new THREE.Color(0.22, 0.23, 0.22);

  function render() {
    renderer.render(scene, camera);
  }
  resizeToClient();
  requestAnimationFrame(render);
}


function onMsg(event) {
  // console.log(`[message] Data received from server: ${event.data}`);
  // console.log("event.data = " + JSON.parse(event.data));

  var received_msg = event.data;

  var obj = JSON.parse(JSON.parse(received_msg));
  if (obj !== null) {
    if (
      obj.hasOwnProperty("DataMapChangedObjectsAddressValue") &&
      obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"] !==
      undefined
    ) {
      let sensorAddr =
        obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"];
      let sensorValue =
        obj["DataMapChangedObjectsAddressValue"][0]["Value"];

      //Accelerometer X Axis
      //if(sensorAddr === this.despToAddrMap.get("Accelerometer X Axis Data")){
      if (sensorAddr === 3) {
        console.log((sensorValue / 16384) * 500);
      }

      sunMesh.position.x = sensorValue;
    }
  }
}

function onOpen(e) {
  console.log("SSE connected");
}

function onError(e) {
  // console.log(`[error] ${error.message}`);
  if (e.eventPhase == EventSource.CLOSED) this.source.close();
  if (e.target.readyState == EventSource.CLOSED) {
    console.log("SSE Disconnected");
  } else if (e.target.readyState == EventSource.CONNECTING) {
    console.log("SSE Connecting ...");
  }
}

function StartRetrieveLiveData() {
  if (!!window.EventSource) {
    this.source = new EventSource("/sse");
  } else {
    console.log("Your browser doesn't support SSE");
  }

  this.source.addEventListener("message", e => this.onMsg(e));

  this.source.addEventListener("open", e => this.onOpen(e), false);

  this.source.addEventListener("error", e => this.onError(e), false);

  // Add here (only mozilla)
  main();
  // Add here

}
StartRetrieveLiveData();

Post a Comment for "JS SSE: Cannot Access Event.data Outside Of OnMsg Callback Function?"