Last active
October 1, 2024 08:06
-
-
Save sebastiaanluca/c80db73d720c3307b4867e6af86369ef 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 + '>'); | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
}) |
@gemins Your trick is helpful for me. Thanks.
Great Gist. Sorry if this is a silly question, noob here. How could I make sure a certain user couldn't or could subscribe to specific channels?
Please help to solve the problem. Here is my repo https://github.com/gasparyanyur/Laravel-SocketIo-Redis-Nodejs/
.. In my case get-data
event not works!
How can I receive message from client in Laravel?
- maker subscribe php file.
== subscribe.php
`<?php
//forever -c php subscribe.php
function f($redis, $chan, $msg) {
switch($chan) {
case 'chan-1':
print "get $msg from $chan\n";
break;
case 'chan-2':
print "get $msg FROM $chan\n";
break;
case 'chan-3':
break;
}
}
ini_set('default_socket_timeout', -1);
$redis = new Redis();
$redis->pconnect('127.0.0.1',6379);
$redis->subscribe(array('chan-1', 'chan-2', 'chan-3'), 'f');
?>`
- use forever and listen subscribe.php
forever -c php subscribe.php
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi quochoangvp, make a emit function with your client and recive in your server with function on:
Client:
socket.emit('send-data', message);
Server:
Try with this example make your own function.