alanaberdeen / AIDA

Annotation of Image Data by Assignment.
https://alanaberdeen.github.io/AIDA
MIT License
56 stars 15 forks source link

Data not visible when browing from another machine #9

Closed rcasero closed 5 years ago

rcasero commented 5 years ago

Hi @alanaberdeen ,

I'm running AIDA on my desktop with

$ node aidaLocal.js 

Running AIDA at http://localhost:3000/

Let's say that the IP address of the desktop is x0.x1.x2.x3.

I have some image and annotations that display fine when browsing from said desktop, either http:localhost:3000/ or http:x0.x1.x2.x3:3000/.

However, if I browse http:x0.x1.x2.x3:3000/ from another machine, e.g. laptop, I still see the AIDA interface, but the Images page says "No data available".

alanaberdeen commented 5 years ago

Hi @rcasero,

Yes, this should work as you say and would be nice if it did! I'll look into it when I get some more time.

rcasero commented 5 years ago

@alanaberdeen ,I've tried a couple of things to fix this. First, changing the IP address of listen from localhost to 0.0.0.0, as it has been suggested that Node.js is not accessible from external IPs on Ubuntu when listening on localhost.

  // Listen to requests
  app.listen(port, "0.0.0.0", () => {
    console.log('\n')
    console.log(`Running AIDA at http://0.0.0.0:${port}/`)
  })

With this, you can still see AIDA locally pointing at your IP address x0.x1.x2.x3:3000, but still not from the outside. My colleague Luis points out that AIDA is throwing the error

0.0.0.0:3000/checkForImages:1 Failed to load resource: net::ERR_EMPTY_RESPONSE
actions.js:13 Error: Network Error
   at t.exports (createError.js:16)
   at XMLHttpRequest.f.onerror (xhr.js:87)

I've also tried changing the ownership of the data directory and all the files within to www-data, the apache2 user. And making the files readable to all, with chmod -R +r data. But those attempts didn't work.

I've also tried to add a header to the CORS,

async function startServer () {
...
  // Allow CORS
  app.use(function (req, res, next) {
...
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT')
...
  })

So far, no success.

rcasero commented 5 years ago

@alanaberdeen Looking into this today with @amccoy95. We think what's happening is that findImages() or checkForImages() are looking into the client's filesystem, not the server's.

We have tested this by @amccoy95 browsing my machine (http://ramons_machine:3000) without running AIDA himself. He can't see data. But if he clones the AIDA files, he can then see example.jpg in http://ramons_machine:3000.

Thus, when @amccoy95 browses http://ramons_machine:3000, my AIDA replies, but it looks for data files in his machine.

We don't know why and @amccoy95 is trying to figure it out, but if you have any ideas, that'd help.

rcasero commented 5 years ago

@alanaberdeen @amccoy95 So further investigation into this. aidaLocal.js contains the code

  // Check for images that may have been added to the directory
  app.post('/checkForImages', async function (req, res) {
    console.log('HERE')
    try {
      await checkForImages()
      res.send('Success, found images')
    } catch (err) {
      console.log('Could not check for images')
      console.log(err)
      res.send('Failed, could not find images')
    }
  })

When you browse http://ramon_machine:3000, it triggers that POST. But POST is to send information from the client to the server. So it makes sense that it's trying to find files in the client, to then send the list to the server.

rcasero commented 5 years ago

I don't know why this works this way, because when I tested Nasullah's version quite a while ago, that one was running on his server, and I could open images living in that server from my desktop.

alanaberdeen commented 5 years ago

Hi @rcasero @amccoy95,

Getting back to this now and I think I've fixed your issues.

The client side code was always sending requests to a localhost address. It will now infer the correct address to communicate with through window.location. It is therefore dependent on where you point your browser window.

I've tested this on a few different laptops and it appears to be working, at least on macOS 10.14.

Note, this very-quick-likely-broken expressJS backend is completely independent from the Grails version Nasullah is running. It was thrown together so people could easily run something locally. Additionally, I imagine he hard coded the API endpoints as there you have the luxury of fixing them in advance. Whereas here the 'server' address is dependent on the machine where the user runs the application.

A few warnings:

  1. I haven't looked into the security of this approach at all.
  2. Multiple people working on the same image will overwrite the same file.

Anyway, check out the latest build and let me know if you have any thoughts

rcasero commented 5 years ago

Hi @alanaberdeen ,

Thanks. I've cloned your master

git clone https://github.com/rcasero/AIDA.git

Installed the dependencies

cd AIDA/dist
npm install

I tried to run it and got the error

$ node aidaLocal.js 
internal/modules/cjs/loader.js:583
    throw err;
    ^

Error: Cannot find module 'chalk'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.Module._load (internal/modules/cjs/loader.js:507:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/rcasero/Software/AIDA/dist/aidaLocal.js:6:15)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

I manually installed the module chalk

npm install chalk

and tried to run again to get the error

node aidaLocal.js 
(node:841) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '1' of undefined
    at startServer (/home/rcasero/Software/AIDA/dist/aidaLocal.js:132:54)
    at Object.<anonymous> (/home/rcasero/Software/AIDA/dist/aidaLocal.js:142:1)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:236:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:560:3)
(node:841) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:841) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
alanaberdeen commented 5 years ago

Hi @rcasero

chalk was oddly missing from the package.json. Fixed this, it will work with the initial npm install now.

I had a look into the error you reported. It is similar to that which a friend encountered: os.networkInterfaces() returns different results depending on platform. I guess you were running on linux/windows and hence it couldn't find the property it expected. I've switched to using the node package ip now so, fingers crossed, it'll work cross-platform.

Hope that all works out for you!

rcasero commented 5 years ago

Hi @alanaberdeen ,

Yes, that fixed it. AIDA can be seen from another machine now. Thanks!