Tuesday, July 7, 2015

FXOS, Node.js, and Friendzy

I'm working with three high school interns this Summer to continue the Firefox OS app development project began by Alex, Aki, and Finn during the last school year.  Yesterday I suggested that they continue work on the Friendzy app that Finn started.

Friendzy is a small client-server app that uses Firefox OS on the client side and Node.js on the server side to allow users to find the location of a group of friends who are using the app together. It has the potential to be fun and engaging for students while providing easy to follow examples of several important technologies.

I've never done anything with node before beyond installing it and running the first example or two in on-line documentation I found.  Since I'm charging Eric, Liam, and Ryan, the three Summer interns, with understanding and then improving Friendzy, I figure I better have a go at it before they do.

The first thing I needed to do was to remove the references Finn had in his code to a specific server we had been using in class, and to replace those references with "localhost".  I added a crude icon, and emailed a friend to ask her if she could make a better one.  Then I deleted my github fork of Finn's version and the revision information in my local copy (by removing the .git directory). Then I created a new repository for Friendzy on github and committed my changed version to a new local repository, and pushed this up to github.

Next I created a VirtualBox VM with Ubuntu 15.04 server edition on which to run the Friendzy server.  I've been making these virtual machines a lot lately, since it allows me to experiment freely with server configuration without fear of messing up my host machine.

(note: my first experiment using the node.js apt packages from the standard Ubuntu repository failed.  npm is not included in the node.js package, and when I installed it separately and used it to install missing node packages, nodejs still couldn't find them.  Rather than try to debug that situation, I decided to try the more recent version of node.js (0.12), which does include npm in the package.  When I did that, it worked).

Now let me see if I can get Friendzy running.  On my fresh server I:
  •  $ curl -sL https://deb.nodesource.com/setup_0.12 | sudo -E bash -
  •  $ sudo aptitude install nodejs
    git comes preinstalled on Ubuntu 15.04 server, so I didn't need to install that. I did need to create an ssh public key and add it to github before I could clone Friendzy.  I already documented that process in a previous post.
    • $ git clone git@github.com:jelkner/Friendzy.git
    • $ cd Friendzy/node
    • $ nodejs server.js

      module.js:340
          throw err;
                ^
      Error: Cannot find module 'express'
          at Function.Module._resolveFilename (module.js:338:15)
          at Function.Module._load (module.js:280:25)
          at Module.require (module.js:364:17)
          at require (module.js:380:17)
          at Object.<anonymous> (/home/[username]/Friendzy/node/server.js:1:81)
          at Module._compile (module.js:456:26)
          at Object.Module._extensions..js (module.js:474:10)
          at Module.load (module.js:356:32)
          at Function.Module._load (module.js:312:12)
          at Function.Module.runMain (module.js:497:10)
    •  $ npm install express
      express@4.13.1 node_modules/express
      ├── escape-html@1.0.2
      ├── merge-descriptors@1.0.0
      ├── array-flatten@1.1.0
      ├── cookie@0.1.3
      ├── utils-merge@1.0.0
      ├── cookie-signature@1.0.6
      ├── methods@1.1.1
      ├── fresh@0.3.0
      ├── range-parser@1.0.2
      ├── path-to-regexp@0.1.6
      ├── content-type@1.0.1
      ├── etag@1.7.0
      ├── vary@1.0.0
      ├── parseurl@1.3.0
      ├── content-disposition@0.5.0
      ├── serve-static@1.10.0
      ├── depd@1.0.1
      ├── qs@4.0.0
      ├── finalhandler@0.4.0 (unpipe@1.0.0)
      ├── on-finished@2.3.0 (ee-first@1.1.1)
      ├── debug@2.2.0 (ms@0.7.1)
      ├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
      ├── type-is@1.6.4 (media-typer@0.3.0, mime-types@2.1.2)
      ├── accepts@1.2.10 (negotiator@0.5.3, mime-types@2.1.2)
      └── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)
    • $ nodejs server.js
      module.js:338
          throw err;
                ^
      Error: Cannot find module 'socket.io'
          at Function.Module._resolveFilename (module.js:336:15)
          at Function.Module._load (module.js:278:25)
          at Module.require (module.js:365:17)
          at require (module.js:384:17)
          at Object.<anonymous> (/home/[username]/Friendzy/node/server.js:3:10)
          at Module._compile (module.js:460:26)
          at Object.Module._extensions..js (module.js:478:10)
          at Module.load (module.js:355:32)
          at Function.Module._load (module.js:310:12)
          at Function.Module.runMain (module.js:501:10)
    • npm install socket.io

      > ws@0.5.0 install /home/jelkner/Friendzy/node/node_modules/socket.io/node_modules/engine.io/node_modules/ws
      > (node-gyp rebuild 2> builderror.log) || (exit 0)

      |
      > ws@0.4.31 install /home/jelkner/Friendzy/node/node_modules/socket.io/node_modules/socket.io-client/node_modules/engine.io-client/node_modules/ws
      > (node-gyp rebuild 2> builderror.log) || (exit 0)

      socket.io@1.3.5 node_modules/socket.io
      ├── debug@2.1.0 (ms@0.6.2)
      ├── has-binary-data@0.1.3 (isarray@0.0.1)
      ├── socket.io-adapter@0.3.1 (object-keys@1.0.1, debug@1.0.2, socket.io-parser@2.2.2)
      ├── socket.io-parser@2.2.4 (isarray@0.0.1, debug@0.7.4, component-emitter@1.1.2, benchmark@1.0.0, json3@3.2.6)
      ├── engine.io@1.5.1 (base64id@0.1.0, debug@1.0.3, engine.io-parser@1.2.1, ws@0.5.0)
      └── socket.io-client@1.3.5 (to-array@0.1.3, indexof@0.0.1, object-component@0.0.3, component-bind@1.0.0, debug@0.7.4, backo2@1.0.2, component-emitter@1.1.2, has-binary@0.1.6, parseuri@0.0.2, engine.io-client@1.5.1)
    • $ nodejs server.js
      module.js:338
          throw err;
                ^
      Error: Cannot find module 'sqlite3'
          at Function.Module._resolveFilename (module.js:336:15)
          at Function.Module._load (module.js:278:25)
          at Module.require (module.js:365:17)
          at require (module.js:384:17)
          at Object.<anonymous> (/home/[username]/Friendzy/node/server.js:5:15)
          at Module._compile (module.js:460:26)
          at Object.Module._extensions..js (module.js:478:10)
          at Module.load (module.js:355:32)
          at Function.Module._load (module.js:310:12)
          at Function.Module.runMain (module.js:501:10)
    • $ npm install sqlite3
      -
      > sqlite3@3.0.8 install /home/[username]/Friendzy/node/node_modules/sqlite3
      > node-pre-gyp install --fallback-to-build

      [sqlite3] Success: "/home/[username]/Friendzy/node/node_modules/sqlite3/lib/binding/node-v14-linux-x64/node_sqlite3.node" is installed via remote
      sqlite3@3.0.8 node_modules/sqlite3
      └── nan@1.8.4
    • $ nodejs server.js
      [LocateFriends] Listening on *:3000
    • ^C
    Next time I'll just do:
    • $ npm install express socket.io sqlite3
    in the beginning and be done with it.  In any case, I have a running Friendzy server on the virtual machine.  My VM has IP address 10.0.0.10.

    To get the client to connect to the server, I needed to change localhost to 10.0.0.10 in two files:
    1. js/app.js
    2. js/usersetup.js
    In both cases the change is near the top of the source file, immediately after:

           IP = "...

    I was able to connect to the server from the Friendzy client running in an emulator, as seen here:
    The terminal window is my ssh session with the VM running the server on 10.0.0.10:3000. The WebIDE connected to a Firefox OS 2.0 emulator running the client appear in two other windows, and the last window is Firefox running on the desktop pointed at 10.0.0.10:3000 to see what would happen.

    Now let's see what Eric, Liam, and Ryan can do with this!

    No comments:

    Post a Comment