skip to Main Content

I have a function which creates a new file in the back-end but the <PlaySound /> component keeps playing the old sound file and not the updated one. The sound file has the same name/path it just has different content.

I tried having the row.text as the key so it would force the component to update when the description of the file updates. I also tried generating a GUID as seed for the url, and also to use no-cache headers but nothing seems to work…

<PlaySound key={ row.text } path={ row.location.path } filename={ row.location.filename } />

This is the PlaySound component

import React, { Component } from 'react';
    
import { genUID } from '../../../helpers/helperFunctions';
    
class PlaySound extends Component
    {
        playSound(path, filename) {
            var endpoint = "http://0.0.0.0:8001/api/stream"
            var url = endpoint + "?path=" + path + "&filename=" + filename + "&seed=" + genUID()
            var audio = new Audio(url);
            console.log(audio);
            audio.load();
            audio.play();        
        }
    
        render() 
        {
            return (
                <div>
                    <span onClick={() => this.playSound(this.props.path, this.props.filename)}>►</span>
                </div>
            );
        }
    }
    
export default PlaySound

Here is my nodejs/express streaming implementation…

app.get(API_VERSION + '/stream', (req, res) =>
{
  const filepath = req.query.path;
  const filename = req.query.filename;

  const file = '/app/audioExport/' + filepath + filename;

  try
  {
    res.writeHead(200, {
      'Cache-Control': 'no-cache, no-store, must-revalidate',
      'Pragma': 'no-cache',
      'Content-Type': 'audio/wav',
    });
    const rstream = fs.createReadStream(file);
    rstream.pipe(res);
  } catch (error) {
    res.json({error: error})
  }
});

** Edit ** Found a related question with no answer.
Reload Audio Cache without Refreshing Page JS/NODE.JS

2

Answers


  1. Chosen as BEST ANSWER

    I was able to solve the problem by following this answer. https://stackoverflow.com/a/39407519/1617800

    By adding the following headers to express now the file does not cache...

      res.header('Access-Control-Allow-Origin', '*');
      res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
      res.header('Pragma', 'no-cache');
      res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
      res.header('Expires', "access plus 1 second");
      req.header['if-none-match'] = '';
      req.header['if-modified-since'] = '';
    

    and also added a unique etag that generated based on the seed

    app.set('etag', res.set('etag', req.query.seed));
    

    The app is for intranet purposes so caching doesn't matter so much in this context. Still, I'll apply the headers only to the /stream endpoint.


  2. I think it would be useful to check the whole flow step-by-step. Changing URL with seed parameter is a good idea to 100% guarantee that caches is not used. It is hard to say if it is working correctly here. What I would do is

    1. Check Chrome DevTools for generated requests. In the Network section it will clearly say size and either it comes from cache or not

    2. It is possible that your Node.js server is using the same file. How do you generate new one? Can it be race-conditioned and you are trying to read it before it is updated

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search