Skip to content

Instantly share code, notes, and snippets.

@Loetfi
Forked from sebastiaanluca/NewMessage.php
Created October 26, 2019 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Loetfi/1a49ee7516dc4751927fa3bbb31c9ea1 to your computer and use it in GitHub Desktop.
Save Loetfi/1a49ee7516dc4751927fa3bbb31c9ea1 to your computer and use it in GitHub Desktop.
Laravel + Redis + NodeJS + Socket.io pub/sub secure server and client supporting multiple rooms, channels, users, … Add `client.js` to your client app, run `node server.js`, and trigger the Laravel event any way you want to broadcast the data.
const PRIVATE_CHANNEL = 'yourprivatehashedchannelid'
//
var io = require('socket.io-client')
var host = window.location.host.split(':')[0]
var socket = io.connect('//' + host + ':8000', {secure: true, rejectUnauthorized: false})
socket.on('connect', function () {
console.log('CONNECT')
socket.on('event', function (data) {
console.log('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 + '>');
})
<?php
namespace App\Events;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class NewMessage extends Event implements ShouldBroadcast
{
use SerializesModels;
public $from;
public $to;
public $message;
public function __construct()
{
$this->from = 'Bond';
$this->to = 'Bean';
$this->message = 'You don\'t say??';
}
public function broadcastOn()
{
return ['yourprivatehashedchannelid', 'thiscouldbeaglobalchanneltoo'];
}
/**
* Get the broadcast event name.
*
* @return string
*/
public function broadcastAs()
{
return 'messages.new';
}
}
const SERVER_PORT = 8000
//
var fs = require('fs')
var https = require('https')
var express = require('express')
var app = express()
var options = {
key: fs.readFileSync('/etc/nginx/ssl/yourapp.key'),
cert: fs.readFileSync('/etc/nginx/ssl/yourapp.crt'),
}
var server = https.createServer(options, app)
var io = require('socket.io').listen(server)
var redis = require('redis')
var ioredis = require('socket.io-redis')
// Multi-server socket handling allowing you to scale horizontally
// or use a load balancer with Redis distributing messages across servers.
io.adapter(ioredis({host: 'localhost', port: 6379}))
//
/*
* Redis pub/sub
*/
// Listen to local Redis broadcasts
var sub = redis.createClient()
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)
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) {
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('disconnect', function () {
console.log('DISCONNECT')
})
})
// Start listening for client connections
server.listen(SERVER_PORT, function () {
console.log('Listening to incoming client connections on port ' + SERVER_PORT)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment