Skip to content

Instantly share code, notes, and snippets.

@Karolass
Created May 26, 2017 12:13
Show Gist options
  • Save Karolass/f9f3b41e7729019b554a18e4c66d0f8c to your computer and use it in GitHub Desktop.
Save Karolass/f9f3b41e7729019b554a18e4c66d0f8c to your computer and use it in GitHub Desktop.
socket io server
const UserTrip = require('./api/model/userTrip.js')
const User = require('./api/model/user.js')
const Location = require('./api/model/location.js')
const jwt = require('jwt-simple')
const env = require('./api/config/env.js')
const { wrap: async } = require('co')
const authCheck = (client, next) => {
if (!client.handshake.headers['x-access-token'] && !client.handshake.query['x-access-token']) {
return next(new Error('[Socket.io] x-access-token is require'))
}
const token = client.handshake.headers['x-access-token'] || client.handshake.query['x-access-token']
try {
const decoded = jwt.decode(token, env.secret)
client.userId = decoded.userId
next()
} catch (err) {
next(new Error(`[Socket.io] x-access-token ${err.message}`))
}
}
const socketRoomJoin = (client, tripId) => {
return new Promise((resolve) => {
client.join(tripId, resolve)
})
}
const broadcastToTrip = async(function*(client, location) {
const user = yield User.findOne({ _id: client.userId }).exec()
client.broadcast.to(client.tripId).emit('location', {
user: {
userId: user.id,
name: user.name,
email: user.email,
photo: user.photo
},
longitude: location.longitude,
latitude: location.latitude
})
})
module.exports = function(io) {
//---- Location ----
const locationIO = io.of('/location')
locationIO.use(authCheck)
locationIO.on('connection', client => {
if (process.env.NODE_ENV != 'test') {
console.log(`[Socket.io] client ${client.userId} connect.`)
}
client.on('disconnect', () => {
if (process.env.NODE_ENV != 'test') {
console.log(`[Socket.io] client ${client.userId} disconnect.`)
}
client.userId = undefined
client.tripId = undefined
})
client.on('joinTrip', async(function*(tripId, res) {
try {
const userTrip = yield UserTrip.findOne({ user: client.userId, trip: tripId }).exec()
if (!userTrip) {
return res('[Socket.io] The trip is not exist or you are not the member of the trip.', null)
}
yield socketRoomJoin(client, tripId)
client.tripId = tripId
const location = yield Location.findOne({ trip: tripId }).exec()
if (location) {
const members = location.members
for (let i = 0; i < members.length; i++) {
const user = yield User.findOne({ _id: members[i].user }).exec()
members[i].user = {
userId: user.id,
name: user.name,
email: user.email,
photo: user.photo
}
}
return res(null, members)
} else {
return res(null, [])
}
} catch (err) {
res('[Socket.io] The trip is not exist or you are not the member of the trip.', null)
}
}))
client.on('shareLocation', async(function*(loc, res) {
try {
let location = yield Location.findOne({ trip: client.tripId }).exec()
if (!location) {
location = new Location({
trip: client.tripId,
members: [
{
user: client.userId,
longitude: loc.longitude,
latitude: loc.latitude,
updatedAt: new Date()
}
]
})
yield location.save()
} else if (location.members.length > 0) {
let isFound = false
for (let i = 0; i < location.members.length; i++) {
if (location.members[i].user == client.userId) {
isFound = true
const member = {
user: client.userId,
longitude: loc.longitude,
latitude: loc.latitude,
updatedAt: new Date()
}
location.members.set(i, member)
}
}
if (!isFound) {
location.members.push({
user: client.userId,
longitude: loc.longitude,
latitude: loc.latitude,
updatedAt: new Date()
})
}
yield location.save()
}
yield broadcastToTrip(client, loc)
return res(null, location.members)
} catch (err) {
res('[Socket.io] The trip is not exist or you are not the member of the trip.', null)
}
}))
})
//------------------
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment