Aquí está mi intento de que funcione lo siguiente:
- expreso : 4.14
- socket.io : 1.5
- pasaporte (usando sesiones): 0.3
- redis : 2.6 (Estructura de datos realmente rápida para manejar sesiones; pero también puedes usar otros como MongoDB. Sin embargo, te animo a usar esto para datos de sesión + MongoDB para almacenar otros datos persistentes como Usuarios)
Dado que es posible que también desee agregar algunas solicitudes de API, también usaremos el paquete http para que tanto HTTP como Web socket funcionen en el mismo puerto.
server.js
El siguiente extracto solo incluye todo lo que necesita para configurar las tecnologías anteriores. Puedes ver la versión completa de server.js que utilicé en uno de mis proyectos aquí .
import http from 'http';
import express from 'express';
import passport from 'passport';
import { createClient as createRedisClient } from 'redis';
import connectRedis from 'connect-redis';
import Socketio from 'socket.io';
// Your own socket handler file, it's optional. Explained below.
import socketConnectionHandler from './sockets';
// Configuration about your Redis session data structure.
const redisClient = createRedisClient();
const RedisStore = connectRedis(Session);
const dbSession = new RedisStore({
client: redisClient,
host: 'localhost',
port: 27017,
prefix: 'stackoverflow_',
disableTTL: true
});
// Let's configure Express to use our Redis storage to handle
// sessions as well. You'll probably want Express to handle your
// sessions as well and share the same storage as your socket.io
// does (i.e. for handling AJAX logins).
const session = Session({
resave: true,
saveUninitialized: true,
key: 'SID', // this will be used for the session cookie identifier
secret: 'secret key',
store: dbSession
});
app.use(session);
// Let's initialize passport by using their middlewares, which do
//everything pretty much automatically. (you have to configure login
// / register strategies on your own though (see reference 1)
app.use(passport.initialize());
app.use(passport.session());
// Socket.IO
const io = Socketio(server);
io.use((socket, next) => {
session(socket.handshake, {}, next);
});
io.on('connection', socketConnectionHandler);
// socket.io is ready; remember that ^this^ variable is just the
// name that we gave to our own socket.io handler file (explained
// just after this).
// Start server. This will start both socket.io and our optional
// AJAX API in the given port.
const port = 3000; // Move this onto an environment variable,
// it'll look more professional.
server.listen(port);
console.info(`🌐 API listening on port ${port}`);
console.info(`🗲 Socket listening on port ${port}`);
sockets / index.js
Nuestro socketConnectionHandler
, simplemente no me gusta poner todo dentro de server.js (aunque perfectamente podría hacerlo), especialmente porque este archivo puede terminar conteniendo bastante código bastante rápido.
export default function connectionHandler(socket) {
const userId = socket.handshake.session.passport &&
socket.handshake.session.passport.user;
// If the user is not logged in, you might find ^this^
// socket.handshake.session.passport variable undefined.
// Give the user a warm welcome.
console.info(`⚡︎ New connection: ${userId}`);
socket.emit('Grettings', `Grettings ${userId}`);
// Handle disconnection.
socket.on('disconnect', () => {
if (process.env.NODE_ENV !== 'production') {
console.info(`⚡︎ Disconnection: ${userId}`);
}
});
}
Material extra (cliente):
Solo una versión muy básica de lo que podría ser el cliente JavaScript socket.io:
import io from 'socket.io-client';
const socketPath = '/socket.io'; // <- Default path.
// But you could configure your server
// to something like /api/socket.io
const socket = io.connect('localhost:3000', { path: socketPath });
socket.on('connect', () => {
console.info('Connected');
socket.on('Grettings', (data) => {
console.info(`Server gretting: ${data}`);
});
});
socket.on('connect_error', (error) => {
console.error(`Connection error: ${error}`);
});
Referencias:
Simplemente no podía hacer referencia dentro del código, así que lo moví aquí.
1: Cómo configurar sus estrategias de Passport: https://scotch.io/tutorials/easy-node-authentication-setup-and-local#handling-signupregistration