socket.io client events are not firing - websocket

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);
});

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/

socket.io buffered messages loss after reconnection

This is on client side
socket.on('connect', () => {
console.log('client connect', socket.id);
const token = getToken();
socket.emit('token', token);
});
socket.on('message', data => {
....
//handle message
});
This is on server side
io.on('connection', (client) => {
client.on('token', token => {
verifyToken(token)
.then(({ _id: clientId }) => {
if (!clientId) return;
if (!connections[clientId]) {
connections[clientId] = new Map();
}
connections[clientId].set(client, 1);
client.on('disconnect', () => {
connections[clientId].delete(client);
});
});
});
});
}
async sendMessageToClients (workspaceId, message) {
const workspace = await getWorkspaceQuery(workspaceId);
if (!workspace) return;
const workspaceMembers = workspace.members.map(({ user }) => user);
for (const memberId of workspaceMembers) {
if (connections[memberId]) {
for (const clientConnection of connections[memberId].keys()) {
console.log('send to client', memberId, message.content, clientConnection.connected, clientConnection.id);
clientConnection.emit('message', message);
}
}
}
};
}
I purposely make a client offline by disconnect the wifi connection (make it in offline mode), what happen is that
a. if the disconnection is short, socket.id stay the same and I can get the buffered message send by other client when comes online;
b. but if I the disconnection is longer, the socket.id will change, and I can't get the buffered message send by other client when comes online.
How should I address that?
Since according to here the messages should be ideally buffered after reconnection.

How to use the controller when working with sockets in AdonisJS

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)
});
});
})

Socket.io+AWS API gateway socket keeps on reconnecting and connect is never fired

AWS recently launched API gateway with sockets and it can proxy to lambda. In my observation AWS api socket is completely wss so I have done custom connect setting which is there in the code section. lambda and other setting I learned tested with wscat successfully as described in this link -
https://hackernoon.com/websockets-api-gateway-9d4aca493d39
But on integration with socket.io in browser it just keeps on reconnecting after 18-19 Seconds and connect is never fired! lambda and api gateway timeout is 30 Seconds which I think can be ignored as it doesn't interrupt the connection with wscat for 4-5 minutes.
I am new to sockets and the code in comments shows failed tries. Also tried googling but couldn't find much about AWS API socket and Socket.io. So any guidance or support is appreciated
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
</head>
<script>
socket = io(
`wss://abcd.execute-api.us-east-1.amazonaws.com/prod`
, {
path: `/prod/`,
forceNew: true,
// autoConnect: false,
// reconnection: false,
upgrade: true,
transports: ['websocket',
'polling',
'flashsocket'
]
});
socket.on('connect', function () {
socket.emit({"action":'message',"data":"hello return"}, () => {
console.log("message Sent");
});
});
// socket.emit({"action":'message',"data":"hello return"}, () => {
// console.log("message"); // true
// });
// socket.on('message', () => {
// console.log("message"); // true
// });
// socket.on("connection", function (socket) {
// console.log("connection")
// })
// socket.on('connect', () => {
// console.log("connect"); // true
// });
// socket.on('connected', () => {
// console.log("connected"); // true
// });
// socket.on('open', () => {
// console.log("open"); // true
// });
// socket.on('disconnect', (reason) => {
// console.log("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('close', (reason) => {
// console.log("close->",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.open();
// // console.log(socket);
// socket.on( (res) => {
// console.log("res", res);
// });
// socket.on('reconnect', (attemptNumber) => {
// console.log("reconnected", attemptNumber); // true
// });
// socket.on('reconnecting', (attemptNumber) => {
// console.log("reconnecting...", attemptNumber); // true
// });
// socket.on('reconnect_error', (error) => {
// console.log("reconnect_error",error);
// });
// socket.on('reconnect_attempt', (error) => {
// console.log("reconnect_attempt->", error)
// // socket.io.opts.transports = ['polling', 'websocket'];
// });
// socket.on('error', (error) => {
// console.log("error->", error);
// });
// socket.on('ping', () => {
// console.log("ping");
// });
// socket.on('pong', () => {
// console.log("ping");
// });
</script>
</html>
I tested below Code in vue2 in Nuxt + Vuetify, I wanted to post for vue3 but I am still trying to get this done in little time I get after day Job. Any corrections are welcome. Thanks
export default {
data() {
return {
socketconnection: {},
listenersStarted: false,
}
},
created() {
this.onLoad()
this.notificationDialog()
this.startListeners()
this.$on('serverSelected', (server) => {
console.log('ran from $on server--', server)
const message = {
text: server,
right: false,
ts: new Date()
}
this.$store.commit('setMessage', message, { root: true })
})
},
methods: {
onLoad() {
try {
if (!localStorage.getItem('_t')) { return true }
if (this.socketconnection === true) {
console.log('socket already there... reconn unrequried!')
return true
}
const token = localStorage.getItem('_t')
const wsUri = `wss://test.example.com/prod?token=${token}`
const websocket = new WebSocket(wsUri)
websocket.onopen = (evt) => {
this.socketconnection = true
}
websocket.onclose = (evt) => { this.onClose(evt) }
websocket.onmessage = (evt) => { this.onMessage(evt) }
websocket.onerror = (evt) => { this.onError(evt) }
} catch (e) { console.log(e) }
},
onClose(evt) {
this.socketconnection = false
console.log('socket closed reconnecting...', evt)
this.onLoad()
},
onMessage(evt) {
console.log('evt---', evt)
this.$emit('serverSelected', evt.data)
},
onError(evt) {
console.log(evt)
},
}
}

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