Skip to content

Commit

Permalink
Merge pull request #74 from brunnerjosh/video-chat
Browse files Browse the repository at this point in the history
Video chat
  • Loading branch information
brunnerjosh authored May 14, 2017
2 parents 997c95f + b16c25f commit 313a90e
Show file tree
Hide file tree
Showing 31 changed files with 1,094 additions and 78 deletions.
22 changes: 0 additions & 22 deletions .dockerignore

This file was deleted.

20 changes: 0 additions & 20 deletions Dockerfile

This file was deleted.

1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node server.js
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ The site is currently hosted through Google Cloud Platform (GCP). The main reaso
- Make sure to lock `package.json` versions by removing `^` from the version number
- Create a version release in GitHub

### Google Cloud Platform
In order to deploy the app to GCP, either set up the SDK locally, or push the code up to the repo's `master` branch in GitHub (which is mirrored to GCP) and log in through Google Cloud Shell and run
### Heroku
In order to deploy the app to Heroku's staging server, run:

`npm run deploy:current`

`npm run deploy`
When you're ready to promote the staging app to production, use the Pipeline in the Heroku Dashboard.

To view server logs, make sure you're connected into a Google Cloud Shell instance and run
To view server logs, make sure you're connected into either the staging or production Heroku app and run:

`gcloud app logs tail -s default`
`heroku logs --tail` or `npm run remote:logs`

---
BEGINE CREATE REACT APP README
Expand Down
6 changes: 0 additions & 6 deletions app.yaml

This file was deleted.

22 changes: 17 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "portfolio-site",
"version": "0.1.5",
"version": "0.1.7",
"private": true,
"homepage": "http://brunnerjosh.github.io",
"bugs": {
"url": "https://github.com/brunnerjosh/brunnerjosh.github.io/issues"
},
"engines": {
"node": ">=4.3.2"
"node": ">=6.x"
},
"proxy": "https://localhost:3001",
"devDependencies": {
"react-scripts": "0.9.5"
},
Expand All @@ -19,25 +20,36 @@
"dotenv": "4.0.0",
"express": "4.15.2",
"flickrapi": "0.6.0",
"fs": "0.0.1-security",
"install": "0.8.8",
"json-loader": "0.5.4",
"lodash": "4.17.4",
"moment": "2.17.1",
"npm": "4.5.0",
"path": "0.12.7",
"portals": "^1.0.9",
"react": "15.4.2",
"react-addons-css-transition-group": "15.4.2",
"react-dom": "15.4.2",
"react-ga": "2.1.2",
"react-input-mask": "^0.8.0",
"react-redux": "5.0.2",
"react-router": "3.0.2",
"react-router-redux": "4.0.7",
"redux": "3.6.0",
"redux-logger": "2.7.4",
"redux-thunk": "2.2.0"
"redux-thunk": "2.2.0",
"socket.io": "^1.7.3",
"uuid": "3.0.1",
"webrtc-adapter": "3.3.3"
},
"scripts": {
"start": "react-scripts start",
"start:production": "NODE_ENV=production node server.js",
"start:proxy": "PORT=3001 NODE_ENV=development node server.js",
"start:proxy-prod": "PORT=3001 NODE_ENV=production node server.js",
"build": "react-scripts build",
"deploy": "npm run build; gcloud app deploy",
"deploy:current": "npm run build; git push heroku $(git rev-parse --symbolic-full-name --abbrev-ref HEAD):master",
"remote:logs": "heroku logs --tail",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
Expand Down
7 changes: 7 additions & 0 deletions routes/api-router.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const io = require('socket.io')();
const express = require('express');
const Flickr = require('flickrapi');
const findRoom = require('./chatManager') ;
const flickrOptions = {
api_key: process.env.FLICKR_KEY,
secret: process.env.FLICKR_SECRET
Expand All @@ -11,6 +13,11 @@ router.get('/', function(req, res) {
res.json({ message: 'success' });
});

router.get('/room', (req, res) => {
const roomId = findRoom().roomId;
res.json({ roomId: roomId });
})

Flickr.tokenOnly(flickrOptions, function(error, flickr) {
if (error) console.error('Flickr error: ', error);
flickr.proxy(router, '/flickr')
Expand Down
56 changes: 56 additions & 0 deletions routes/chatManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const rooms = [];
const OPEN_ROOM_DURATION = 2; // mins

function addDashes (num)
{
return num.slice(0,3)+'-'+num.slice(3,6)+'-'+num.slice(6);
}

function isUniqueRoom (roomId) {
for (var i = 0; i < rooms.length; i++){
if (rooms[i].roomId === roomId) {
return false;
}
}
return true;
}

function createNewRoom () {
return {
createdAt: (new Date()).getTime(),
roomId: addDashes(Math.floor(100000000 + Math.random() * 900000000).toString())
};
}

function generateRoomId () {
var newRoom = createNewRoom();
if (isUniqueRoom(newRoom.roomId)) {
rooms.push(newRoom);
return rooms[rooms.length - 1];
}
return null;
}

function findRoom () {
const lastRoom = rooms[rooms.length - 1] || null;
if (lastRoom) {
const timeNow = (new Date()).getTime();
const fiveMinsBefore = timeNow - OPEN_ROOM_DURATION * 60 * 1000;
if (lastRoom.createdAt > fiveMinsBefore) {
console.log('Returning previously created room', lastRoom);
return lastRoom;
} else {
while (true) {
var newRoom = generateRoomId();
if (newRoom) {
console.log("Creating new chat room: ", newRoom)
return newRoom;
}
}
}
} else {
return generateRoomId();
}
}

module.exports = findRoom;
68 changes: 68 additions & 0 deletions routes/socket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const io = require('socket.io')();

const socketIdToNames = {}

//------------------------------------------------------------------------------
// Credit to: https://github.com/oney/react-native-webrtc-server
// WebRTC Signaling
function socketIdsInRoom(roomId) {
var socketIds = io.nsps['/'].adapter.rooms[roomId];
if (socketIds.sockets) {
var collection = [];
for (var key in socketIds.sockets) {
collection.push(key);
}
return collection;
} else {
return [];
}
}

io.on('connection', function(socket){
console.log('SOCKET_CONNECT: ' + socket.id);

socket.on('disconnect', function(){
console.log('SOCKET_DISCONNECT: ' + socket.id + ': ' + socketIdToNames[socket.id]);
delete socketIdToNames[socket.id];
if (socket.room) {
var room = socket.room;
io.to(room).emit('leave', socket.id);
socket.leave(room);
}
});

/**
* Callback: list of {socketId, name: name of user}
*/
socket.on('join', function(joinData, callback){ //Join room
let roomId = joinData.roomId;
let name = joinData.name;
socket.join(roomId);
socket.room = roomId;
socketIdToNames[socket.id] = name;
var socketIds = socketIdsInRoom(roomId);
let friends = socketIds.map((socketId) => {
return {
socketId: socketId,
name: socketIdToNames[socketId]
}
}).filter((friend) => friend.socketId != socket.id);
callback(friends);
// broadcast
friends.forEach((friend) => {
io.sockets.connected[friend.socketId].emit('join', {
socketId: socket.id, name
});
});
console.log('SOCKET_JOIN: ', joinData);
});

socket.on('exchange', function(data){
data.from = socket.id;
var to = io.sockets.connected[data.to];
to.emit('exchange', data);
});

});

module.exports = io;
37 changes: 26 additions & 11 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
require('dotenv').config();
const fs = require('fs');
const path = require('path');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const routes = require('./routes/api-router');

const app = express();
const socket = require('./routes/socket');
const config = require('./static.json');
const port = process.env.PORT || 8080;
const config = {
root: 'build/',
home: 'index.html'
const options = process.env.NODE_ENV === 'development' ? {
key: fs.readFileSync('../.localhost-ssl/key.pem'),
cert: fs.readFileSync('../.localhost-ssl/cert.pem')
} : {};

// http://stackoverflow.com/questions/7185074/heroku-nodejs-http-to-https-ssl-forced-redirect
const forceSSL = (req, res, next) => {
return req.headers['x-forwarded-proto'] !== 'https'
? res.redirect(['https://', req.get('Host'), req.url].join(''))
: next();
};

const secureMode = process.env.HTTPS === 'true' && process.env.NODE_ENV === 'development';
const server = secureMode ? https.createServer(options, app) : http.createServer(app);
socket.listen(server);

if (process.env.NODE_ENV === 'production') app.use(forceSSL);
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use('/api', routes);
app.use(express.static(__dirname + `/${config.root}`));

app.get('*', (req, res) => res.sendFile( path.resolve(__dirname, config.root, config.home)) );
app.use(express.static(__dirname + `/${config['root']}`));
app.get('*', (req, res) => res.sendFile( path.resolve(__dirname, config['root'], config.routes['/**'])) );

app.listen(port, function (err) {
server.listen(port, function (err) {
if (err) {
console.error(err);
return;
}

console.log('Express server listening on %d, in %s mode', port, app.get('env'));
console.log( (secureMode ? 'HTTPS' : 'HTTP') + ' Express server listening on %d, in %s mode', port, app.get('env'));
});

14 changes: 14 additions & 0 deletions src/Actions/WebRTC.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Api from '../Services/Api';
import { initWebRTC } from '../Services/WebRTC';

export function findOpenChatRoom () {
return dispatch => {
Api.get('api/room')
.then( data => {
initWebRTC(data.body.roomId)(dispatch);
})
.catch( err => {
dispatch({ type: 'GET_CHAT_ROOM_ERROR' })
})
}
}
9 changes: 8 additions & 1 deletion src/Assets/medium_posts.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
{
"items": [
{
"title": "From Hawaiian Farms to Helpful Human — The Story of How I Became a Developer by Accident",
"pubdate": "Fri, 28 April 2017 17:29:01 GMT",
"link": "https://medium.com/helpful-human/from-hawaiian-farms-to-helpful-human-the-story-of-how-i-became-a-developer-by-accident-352d2b9f421e",
"img": "https://cdn-images-1.medium.com/max/2000/1*hBHY59BtiyU0Ng6JBLKpgA.jpeg",
"description": "I grew up on the beautiful Big Island of Hawaii. My father moved to the Big Island 36 years ago to sell “puka shell” necklaces..."
},
{
"title": "Embracing Dyslexia As A Software Engineer",
"pubdate": "Tue, 14 Mar 2017 17:29:01 GMT",
"link": "https://medium.com/helpful-human/embracing-dyslexia-as-a-software-engineer-86419a94bd94",
"img": "https://cdn-images-1.medium.com/max/1000/1*reqzxN6y8YoDeEQLLq2cJQ.png",
"description": "Growing up in a small private school, I did not have much exposure to other types of thinkers. So, when I would slip up when reading out"
"description": "Growing up in a small private school, I did not have much exposure to other types of thinkers. So, when I would slip up when reading out..."
}
]
}
2 changes: 2 additions & 0 deletions src/Components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Theme from '../Components/Theme';

import '../Styles/Reset.css';
import '../Styles/index.css';
import '../Styles/Button.css';
import '../Styles/Input.css';
import '../Styles/App.css';
import '../Styles/Content.css';

Expand Down
Loading

0 comments on commit 313a90e

Please sign in to comment.