Skip to content

Instantly share code, notes, and snippets.

@EvilFreelancer
Last active September 26, 2022 07:43
Show Gist options
  • Save EvilFreelancer/3f9cf53ecd1c02ba329cfceeefd51d3b to your computer and use it in GitHub Desktop.
Save EvilFreelancer/3f9cf53ecd1c02ba329cfceeefd51d3b to your computer and use it in GitHub Desktop.
Simple Socket.IO server and client on JavaScript
const PRIVATE_CHANNEL = 'channel_private';
const GLOBAL_CHANNEL = 'default';
var io = require('socket.io-client');
var socket = io.connect('http://localhost:8080');
var channel = null;
socket.on('connect', function () {
console.log('CONNECT');
socket.on('events.new', function (data) {
console.log('EVENT', data)
});
socket.on('views.new', function (data) {
console.log('NEW VIEW OF EVENT', data)
});
socket.on('messages.new', function (data) {
console.log('NEW PRIVATE MESSAGE', data)
});
socket.on('disconnect', function () {
console.log('disconnect')
});
// Kick it off
// Can be any channel. For private channels, Laravel should pass it upon page load (or given by another user).
socket.emit('subscribe-to-channel', {channel: PRIVATE_CHANNEL});
console.log('SUBSCRIBED TO <' + PRIVATE_CHANNEL + '>');
socket.emit('subscribe-to-channel', {channel: GLOBAL_CHANNEL});
console.log('SUBSCRIBED TO <' + GLOBAL_CHANNEL + '>');
});
const SERVER_PORT = 8080;
const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const redis = require('redis');
const ioredis = require('socket.io-redis');
io.adapter(ioredis({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT
}));
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
/*
* Redis pub/sub
*/
// Listen to local Redis broadcasts
const sub = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT
});
sub.on('error', function (error) {
console.log('ERROR ' + error)
});
sub.on('subscribe', function (channel, count) {
console.log('SUBSCRIBE', channel, count)
});
// Handle messages from channels we're subscribed to
sub.on('message', function (channel, payload) {
console.log('INCOMING MESSAGE', channel, payload);
if (isJson(payload)) {
payload = JSON.parse(payload);
}
// Merge channel into payload
payload.data._channel = channel;
// Send the data through to any client in the channel room (!)
// (i.e. server room, usually being just the one user)
io.sockets.in(channel).emit(payload.event, payload.data)
});
/*
* Server
*/
// Start listening for incoming client connections
io.sockets.on('connection', function (socket) {
console.log('NEW CLIENT CONNECTED');
socket.on('subscribe-to-channel', function (data) {
if (isJson(data)) {
data = JSON.parse(data);
}
console.log('SUBSCRIBE TO CHANNEL', data);
// Subscribe to the Redis channel using our global subscriber
sub.subscribe(data.channel);
// Join the (somewhat local) server room for this channel. This
// way we can later pass our channel events right through to
// the room instead of broadcasting them to every client.
socket.join(data.channel)
});
socket.on('unsubscribe-from-channel', function (data) {
if (isJson(data)) {
data = JSON.parse(data);
}
console.log('UNSUBSCRIBE FROM CHANNEL', data);
// Unsubscribe from the Redis channel
sub.unsubscribe(data.channel);
// Leave from this channel
socket.leave(data.channel)
});
socket.on('disconnect', function () {
console.log('DISCONNECT')
});
});
server.listen(SERVER_PORT, function () {
console.log('Listening on port ' + SERVER_PORT);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment