How to use the controller when working with sockets in AdonisJS - socket.io

How to call the controller when I do emit in socket.io
I want that when calling emit from the client the data is first saved in the db and then sent to it.
My code:
import SocketIO from '#ioc:Socket.IO'
SocketIO.afterStart(() => {
const io = SocketIO.io()
io.use((socket, next) => {
//Middleware
next()
});
io.on('connection', (socket) => {
io.emit(`room.6`, {
type: 'connected'
//role: socket.handshake.query.user
});
socket.on('disconnect', () => {
io.emit(`room.6`, {
type: 'disconnected',
//role: socket.handshake.query.user
})
});
socket.on(`room.6`, (data) => {
io.emit(`room.6`, //Here the controller should be called)
});
});
})

Related

socket.io client 's namespace invalid

I am running on the latest version of socket.io, the server code and client code below works well.
// server
const { Server } = require("socket.io"),
http = require('http');
const httpserver = http.createServer();
io.on("connection", async (socket) => {
socket.on("error", (err) => {
console.log(err.message);
});
socket.on('disconnect', function () {
console.log('socket disconnect');
})
});
const io = new Server(httpserver, {
cors: { origin: "*", methods: ["GET", "POST"],}
});
httpserver.listen(3001, () => {
console.log('listening on *:3001');
});
// client
import { io, Socket } from "socket.io-client";
const socket = io('ws://127.0.0.1:3001', {
transports: ["websocket"]
});
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
then I tried to work with namespace in socket.io
// server
io.of("device").on("connection", async (socket) => {
socket.on("error", (err) => {
console.log(err.message);
});
socket.on('disconnect', function () {
console.log('socket disconnect');
})
});
// client
const socket = io('ws://127.0.0.1:3001/device', {
transports: ["websocket"]
});
running the code gives me an error saying
'connect_error due to Invalid namespace''
I can't figure out what goes wrong
Using ws://127.0.0.1:3001/device means you are trying to reach the namespace named '/advice', which does not exist on the server.
I think you are looking for the path option instead:
const socket = io("ws://127.0.0.1:3001", {
path: "/device",
transports: ["websocket"]
});
References:
https://socket.io/docs/v4/client-initialization/
https://socket.io/docs/v4/client-options/#path
https://socket.io/docs/v4/namespaces/

SocketIO 4 - won't emit to the room

I have following server code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const {jwtDecode, jwtVerify, resignJwt} = require('jwt-js-decode')
const secret =
"xxxxxxx";
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
let servantID = ''
io.use((socket, next) => {
const header = socket.handshake.headers["authorization"];
jwtVerify(header, secret).then((res) => {
if (res === true)
{
const jwt = jwtDecode(header);
servantID = jwt.payload.iss;
return next()
}
return next(new Error("authentication error"));
});
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
socket.on("join", (room, cb) => {
console.log('Joined ' + room);
socket.join(room);
cb(`Joined the best room ${room}`)
});
socket.on('newOrder', function (data) {
socket.to('servant').emit('this', data);
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
And client side code:
socket.emit('join', 'servant', message => {
console.log(message)
})
socket.on('this', () => {
console.log('this event')
})
socket.emit('newOrder', 'data')
When I emit like this:
socket.to('servant').emit('this', data);
the client doesn't receive anything, but if I emit without room:
socket.emit('this', data);
the event and data are received on the client side.
What am I doing wrong here?

Not able to use alias across tests in Cypress

I am trying to create a framework for API tests using cypress and I am facing an issue accessing the data between tests using an alias. Is there something that I am missing?
custom.js
Cypress.Commands.add('getResource', function (uri) {
cy.request({
url: uri,
method: 'GET'
}).then(function (response) {
return cy.wrap(response);
});
});
test.js
exports.__esModule = true;
context('requests', function () {
it('validate get call response', function () {
let re = cy.getResource('https://reqres.in/api/users?page=2','resp')
re.then(function (response) {
cy.wrap(response.body).as('respbody');
cy.wrap(response.status).as('respstatus');
//cy.log(JSON.stringify(response.body));
});
});
it('Tests test', function () {
cy.wait('#respbody').then((body) => {
console.log(JSON.stringify(body));
});
});
});
cypress version - 8.2.0
By design cypress cleans up aliases after each test. So you can do something like this cypress recipe
Your getResource custom command is taking just one parameter, hence we are passing just one papameter.
exports.__esModule = true;
let responseBody;
let responseStatus;
context('requests', () => {
before(() => {
cy.getResource('https://reqres.in/api/users?page=2')
.then(function(response) {
responseBody = response.body
responseStatus = response.status
})
})
beforeEach(() => {
cy.wrap(responseBody).as('responseBody')
cy.wrap(responseStatus).as('responseStatus')
})
it('Get Response status', function() {
cy.wait('#responseStatus').then((responseStatus) => {
console.log(responseStatus)
})
})
it('Get Response Body', function() {
cy.wait('#responseBody').then((responseBody) => {
console.log(JSON.stringify(responseBody))
})
})
})

socket.io client events are not firing

I am trying to run my client without my server connected (on purpose) and catch ERR_CONNECTION_REFUSED error and display it to the user. I read here that this can be achieved using socket events, specifically connect_error
Below in my code, I can never get the events to fire and display the console logs inside. logging this.io.socket prints stuff but none of the events do.. why is that?
$.ajax(args)
.done((msg) => {
this.io.socket.on('connect', msg => {
console.log('connect socket io', msg)
})
resolve(msg);
})
.fail((jqXHR, msg) => {
return new Promise((resolve, reject) => {
console.log('inside promise of fail() - this.io.socket', this.io.socket) // this will log data to console
this.io.socket.on('connect_error', msg => {
console.log('connect_error socket io', msg)
})
this.io.socket.on('connect_failed', (msg) => {
console.log('connect_failed', msg);
});
// return some error here for user
})
});
From what I see, you are attempting to wire up the event handlers only if you get a bad response from your first ajax call. This will not result in any of the socket.io event handlers being initiated.
Move the event handler into the code where you initialize the socket instance.
See below for a full example where all the manager and socket events will be logged to console.
$.ajax(args)
.done((msg) => {
// connect to your server
const socket = io('http://localhost:3000', {
transports: ['websocket']
});
// manager events
//_________________________________________________________________________________________________
socket.io.on('connect_error', (err) => {
console.error(`manager:connect_error ${err}`);
});
socket.io.on('connect_timeout', () => {
console.error(`manager:connect_timeout`);
});
socket.io.on('reconnect_attempt', (attempt) => {
console.error(`manager:reconnect_attempt ${attempt}`);
});
socket.io.on('reconnecting', (attempt) => {
console.error(`manager:reconnecting ${attempt}`);
});
socket.io.on('reconnect_error', (err) => {
console.error(`manager:reconnect_error ${err}`);
});
socket.io.on('reconnect_failed', () => {
console.error(`manager:reconnect_failed`);
});
//_________________________________________________________________________________________________
// socket events
//_________________________________________________________________________________________________
socket.on('connect', () => {
console.log(`socket:connect ${socket.connected}`);
});
socket.on('connect_error', (err) => {
console.error(`socket:connect_error ${err}`);
});
socket.on('connect_timeout', (timeout) => {
console.error(`socket:connect_timeout ${timeout}`);
});
socket.on('error', (err) => {
console.error(`socket:error ${err}`);
});
socket.on('disconnect', (reason) => {
console.info(`socket:disconnect ${reason}`);
if (reason === 'io server disconnect') {
// the disconnection was initiated by the server, you need to reconnect manually
socket.connect();
}
// else the socket will automatically try to reconnect
});
socket.on('reconnect', (attempt) => {
console.error(`socket:reconnect ${attempt}`);
});
socket.on('reconnect_attempt', (attempt) => {
console.error(`socket:reconnect_attempt ${attempt}`);
});
socket.on('reconnecting', (attempt) => {
console.error(`socket:reconnecting ${attempt}`);
});
socket.on('reconnect_error', (err) => {
console.error(`socket:reconnect_error ${err}`);
});
socket.on('reconnect_failed', () => {
console.error(`socket:reconnect_failed`);
});
//_________________________________________________________________________________________________
// custom events
//_________________________________________________________________________________________________
socket.on('hello', (message) => {
console.info(message);
socket.emit('hello', {foo: 'baz'});
});
//_________________________________________________________________________________________________
resolve(msg);
})
.fail((jqXHR, msg) => {
console.error(msg);
});

HapiJS and Socket IO not emit

I'm trying to setup socket.io with hapi. I've setup a barebones repo here: https://github.com/imcodingideas/socketio-hapi-example but this is the gist of it. On the server.js I am listening for a connection
io.sockets.on('connection', (socket) => {
socket.emit({ msg: 'welcome' })
})
and on the client I'm sending a connection
socket.on('msg', data => {
console.log(data)
socket.emit('my other event', { my: 'data' })
})
I'm not getting any cors errors or nothing so it's able to connect.
Your code does work and it doesn't matter where you put the server.start().
The problem is your client side code. The event socket.on('connection') does not exist for the socket.io client. The event is called connect.
IO - Event: ‘connect’ Documentation
The following code snippet should work.
const socket = io('http://localhost:8081');
socket.on('connect', data => {
console.log('connected');
});
socket.on('msg', data => {
console.log(data);
});
setTimeout(() => {
socket.emit('another event', 'another events data')
}, 2000)
server:
const init = async () => {
const io = SocketIO.listen(server.listener)
io.sockets.on('connection', (socket) => {
socket.emit('msg', 'welcome')
socket.on('another event', (data) => {
console.log(data);
})
})
await server.start()
console.log(`Server running at: ${server.info.uri}`)
}
Do not start the server before you initialize the Socket Listener.
'use strict'
const Hapi = require('hapi')
const SocketIO = require('socket.io')
const server = Hapi.server({
port: 8081,
host: 'localhost'
})
const init = async () => {
// await server.start() // not here
const io = SocketIO.listen(server.listener)
io.sockets.on('connection', (socket) => {
socket.emit('msg', 'welcome')
})
await server.start() // but start it here.
console.log(`Server running at: ${server.info.uri}`)
}
init()
Pro tip
You can use Firecamp to test socket events and listeners visually

Resources