Socket.io extend Socket class - node.js

I want to create a new function for the Socket class in socket.io but i have no idea how to accomplish this.
I would like to call the function like this socket.nearby().emit().
My code below:
const server = require('http').createServer()
const socketio = require('socket.io')
const io = socketio(server)
io.on('connection', (socket) => {
socket.on('join', (data, callback) => {
// process data
socket.nearby().emit('join', data)
callback(data)
})
})
io.prototype.nearby = function() {
// do function
}

io is not the constructor for the socket.io Socket class so that's why what you showed wouldn't work as you don't have the correct prototype.
The simplest way, without delving into the socket.io source code to try to find how you can access the socket prototype, would be to just do this:
const server = require('http').createServer()
const socketio = require('socket.io')
const io = socketio(server)
io.on('connection', (socket) => {
// add our custom method to each newly created socket object
socket.nearby = function() {
// add implementation code here
}
socket.on('join', (data, callback) => {
// process data
socket.nearby().emit('join', data)
callback(data)
})
})

Related

Using socket.io connection as a module

I created a queue system via Rabbitmq and send notifications to users via socket. There are 3 files basically.
-index.js //some functions to save data and send to Rabbitmq
-socket.js //socket io modules
-consumer.js //some functions to consume data from Rabbitmq
When npm run index.js and consumer.js are started.
index.js
const Express = require('express');
const app = Express();
//init server
server = app.listen(3000);
//init socket io
require('./socket').initialize(server);
socket.js
const sio = require('socket.io');
let io;
module.exports = {
//Initialize the socket server
initialize: (server) => {
io = sio(server, {
cors: {
origin: '*',
}
});
io.on('connection', (socket) => {
console.log('New client connected with id = ', socket.id);
socket.on('disconnect', () => {
console.log("User disconnected");
});
});
},
//return the io instance
getInstance: () => {
return io;
}
}
consumer.js
const socket = require('./socket');
const io = socket.getInstance();
console.log("io", io);
//io is undefined
Io returns undefined in consumer.js. Where is mistake?
You can't call socket.getInstance() until someone has called socket.initialize() first.
You don't show where consumer.js is loaded so we can't follow the full sequence of module loading, but it appears that consumer.js is getting loaded before you initialize socket and thus it is trying to call socket.getInstance() before there's a socket instance to get.
When using methods that return state that built from previous methods, it is obviously important that things are called in the right order.

How can i receive emit response within laravel

I am using socket.io and node.js for a socket connection, I am sending data via API to a socket using below laravel code.
its working perfect after all procedure in a socket.js file which is running in a terminal with node socket.js. I just want a response on the same function where I publish the event, is it possible with this or I need to do something else.
Note: everything is perfect just need a response in the same function where I publish
Thanks
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use App\Http\Requests;
use LRedis;
class MessageController extends Controller{
public function store(Request $request){
$data = [
'id'=>1,
'game_name'=>'PUB',
];
$redis = LRedis::connection();
$redis->publish('message', json_encode($data));
}
}
////// node node.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(3000, function () {
console.log('Listening on Port 3000');
});
redisClient.subscribe('message');
redisClient.on("message", function (channel, data) {
const dataj = JSON.parse(data);
console.log(data);
///// send data to client which is connected with me
io.emit("eventsend", {
"id": dataj.id,
"game": dataj.game,
});
});
io.on('connection', function (socket) {
/////////////////////// send by client
socket.on("eventrec", function (data) {
console.log(data);
});
//console.log("Connected!");
/////////////////////// send by client
socket.on("success_repo", function (data) {
////////// i want this response in my laravel file where i publish the message event
console.log(data);
});
socket.on('disconnect', function () {
redisClient.unsubscribe('message');
});
});

Unable to connect to socket IO locally in reactjs?

I am using nodeJs as backend and reactJs as my frontend the thing is I emitted a socket emit function from node
var server = require('http').createServer();
var io = require('socket.io')(server);
io.emit('quantity_check', 'KR')
now the issue is I'm unable to catch the emit
let serverUrl = 'localhost:3008'
const socket = socketIOClient(serverUrl);
socket.on("quantity_check", data => this.setState({ kiiii: data }));`
const socket = socketIOClient(serverUrl);
I'm checking this locally even i tried with my ip its not connecting I am not sure where the issue occurs
pc:nodejs and reactjs running on different ports
Can you post the code of you node server file and the react file where are you are listening to the sockets?. Anyway i hope that emit event is inside the connection
io.on('connection', function(socket) {
io.emit('quantity_check', 'KR')
}
and did you use the life cycle method componentDidMount to receive message
componentDidMount() {
socket.on("quantity_check", data => {
console.log(data);
});
}
Try something like this.
server
const server = require('http').createServer();
const io = require('socket.io')(server);
io.on('connect', (socket) => {
io.emit('quantity_check', 'KR');
});
Client(React side)
import io from 'socket.io-client';
const socket = io('http://localhost:3008');
export class App extends Component {
componentDidMount() {
socket.on('connect', () => {
console.log(socket.connected);
});
socket.on("quantity_checke", data => {
console.log(data);
});
}
render().......
}

Socket.io with Adonis.js

I am using Adonis 4.1.0 and Adonis-websocket is only been available for v3. Can anyone tell me workaround for using socket.io with Adonis 4.1.0?
apparently they have been working on this not long ago, it was based on socket.io but because of some issues like memory leaks and others, they decided to use websockets directly instead, check these discussions :
https://github.com/adonisjs/discussion/issues/51
https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
have you tried using socket.io without relying on Adonis ? ,
something like :
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
But you should be able to do this with Adonis by now according to : https://github.com/adonisjs/adonis-websocket-protocol
Example :
const filereader = require('simple-filereader')
const msgpack = require('msgpack-lite')
const packets = require('#adonisjs/websocket-packets')
const client = new WebSocket('ws://localhost:3000/adonis-ws')
client.onopen = function () {
// TCP connection created
}
client.onerror = function () {
// TCP connection error
}
client.onmessage = function (message) {
filereader(message, function (error, payload) {
const packet = msgpack.decode(payload)
handlePacket(packet)
})
}
function handlePacket (packet) {
if (packets.isOpenPacket(packet)) {
console.log('Server ack connection. Make channel subscriptions now')
}
if (packets.isJoinAck(packet)) {
console.log('subscription created for %s', packet.d.topic)
}
}
check this for broadcast examples using WS : https://github.com/websockets/ws#broadcast-example
Create start/socket.js file and paste following code inside it.
const Server = use('Server')
const io = use('socket.io')(Server.getInstance())
io.on('connection', function (socket) {
console.log(socket.id)
})
From Virk Himself in this forum:https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
create a standalone socket io configuration file in start/socket.js
const io = require('socket.io')();
io.listen(3000);
io.on('connection', function (socket) {
console.log(socket.id)
})
to start your socket io server you can configure your server.js as below
new Ignitor(require('#adonisjs/fold'))
.appRoot(__dirname)
.preLoad('start/socket') //path of socket.js
.fireHttpServer()
.catch(console.error)
now when you start your server then it will start along with socket io

Get parent `io` from `socket`

In Socket.IO you can send a message to *everyone* with the following:
const io = require("socket.io");
io.broadcast.emit("message", data);
You can also send a message to *everyone but one person* using a pattern like so:
const io = require("socket.io");
io.on("connection", function(socket) {
socket.on("message", function(msg) {
socket.broadcast.emit("message", msg);
});
});
This allows for the creation of simple chat apps and the like
Now suppose I have the socket handler defined in another file:
// index.js
const io = require("socket.io");
const handler = require("./handler.js");
io.on("connection", function(socket) {
socket.on("message", handler);
});
// handler.js
module.exports = function(socket) {
socket.broadcast.emit("message", msg);
}
In this situation, I want to send a message to everyone - including the socket that initiated the message. So given the socket, how do I get access to its parent io object?
I've tried some things like:
socket.io.broadcast
socket.server.broadcast
socket.server.eio.broadcast
etc
But none of these seem to work
What about passing in the io to the handler? Originally the handler function would accept a payload (msg in your handler) not a socket?
// index.js
const io = require("socket.io");
const handler = require("./handler.js");
io.on("connection", function(socket) {
socket.on("message", data => handler(io, data) );
});
// handler.js
module.exports = function(socket, msg) {
socket.broadcast.emit("message", msg);
}

Resources