Cannot connect to socketio server from client in nodejs - javascript

const { io } = require("socket.io-client");
const botSocket = io("http://localhost:1025");
botSocket.connect();
botSocket.on("connect_failed", function () {
console.log("Sorry, there seems to be an issue with the connection!");
});
botSocket.onAny((data) => {
console.log(data, "bot connect");
});
botSocket.on("connection", (data) => {
console.log(data, "bot conenct");
});
Here is my code, but when I run it, nothing is logged ever, what am I doing wrong?

Related

Can a Twilio Function call a Redis instance in the cloud?

I'm trying to call Redis from a Twilio Function (serverless) and I don't see incoming connections in my Redis log.
Is this setup viable?
Sample code follows:
const Redis = require('ioredis');
const fs = require('fs');
exports.handler = function (context, event, callback) {
const config = Runtime.getAssets()['config.json'].open();
let redisClientConfig = JSON.parse(config).redisConfig;
let contactCacheTime = JSON.parse(config).contactCacheTime;
if (!redisClientConfig) {
throw new Error('Redis config not set.');
}
const redisClient = new Redis(redisClientConfig);
redisClient.on('error', (err) => {
console.error(`Cannot connect to redis, reason: ${(err.message || err)}`);
});
redisClient.getex('mhn-twilio-bot-contact:'.concat(event.contactKey), 'EX', contactCacheTime)
.then((res) => {
if (!res) {
redisClient.setex('mhn-twilio-bot-contact:'.concat(event.contactKey), contactCacheTime, '<CACHED-VALUE>');
}
callback(null, { cached: res ? true : false });
})
.catch((err) => {
callback(null, { cached: false });
});
};

ReactJs : WebSocket is closed before the connection is established

Full-Stack Web Application using React, Node Js, Web sockets. My project is based on ReactJs with server on Express. When trying to connect to socket.io from chrome I receive "WebSocket is closed before the connection is established" message.
"editorpage.js"
useEffect(() => {
const init = async () => {
socketRef.current = await initSocket();
socketRef.current.on('connect_error', (err) => handleErrors(err));
socketRef.current.on('connect_failed', (err) => handleErrors(err));
function handleErrors(e) {
console.log('Socket Error', e);
toast.error('Socket Connection Failed, Try Again Later.');
reactNavigator('/');
}
socketRef.current.emit(ACTIONS.JOIN, {
roomId,
username: location.state?.username,
});
// Listening for joined event
socketRef.current.on(
ACTIONS.JOINED,
({ clients, username, socketId }) => {
if (username !== location.state?.username) {
toast.success(`${username} joined the room.`);
console.log(`${username} joined`);
}
setClients(clients);
socketRef.current.emit(ACTIONS.SYNC_CODE, {
code: codeRef.current,
socketId,
});
}
);
// Listening for disconnected
socketRef.current.on(
ACTIONS.DISCONNECTED,
({ socketId, username }) => {
toast.success(`${username} left the room.`);
setClients((prev) => {
return prev.filter(
(client) => client.socketId !== socketId
);
});
}
);
};
init();
return () => {
socketRef.current?.disconnect();
socketRef.current?.off(ACTIONS.JOINED);
socketRef.current?.off(ACTIONS.DISCONNECTED);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
This error when running on google chrome
"socket.js"
import { io } from 'socket.io-client';
export const initSocket = async () => {
const options = {
'force new connection': true,
reconnectionAttempt: 'Infinity',
timeout: 10000,
transports: ['websocket'],
};
return io(process.env.REACT_APP_BACKEND_URL, options);
};
"server.js"
const express = require('express');
const app = express();
const http = require('http');
const {
Server
} = require('socket.io');
const ACTIONS = require('./src/Actions');
const server = http.createServer(app);
const io = new Server(server);
const userSocketMap = {};
function getAllConnectedClients(roomId) {
// Map
return Array.from(io.sockets.adapter.rooms.get(roomId) || []).map(
(socketId) => {
return {
socketId,
username: userSocketMap[socketId],
};
}
);
}
io.on('connection', (socket) => {
console.log('socket connected', socket.id);
socket.on(ACTIONS.JOIN, ({
roomId,
username
}) => {
userSocketMap[socket.id] = username;
socket.join(roomId);
const clients = getAllConnectedClients(roomId);
clients.forEach(({
socketId
}) => {
io.to(socketId).emit(ACTIONS.JOINED, {
clients,
username,
socketId: socket.id,
});
});
});
socket.on(ACTIONS.CODE_CHANGE, ({
roomId,
code
}) => {
socket.in(roomId).emit(ACTIONS.CODE_CHANGE, {
code
});
});
socket.on(ACTIONS.SYNC_CODE, ({
socketId,
code
}) => {
io.to(socketId).emit(ACTIONS.CODE_CHANGE, {
code
});
});
socket.on('disconnecting', () => {
const rooms = [...socket.rooms];
rooms.forEach((roomId) => {
socket.in(roomId).emit(ACTIONS.DISCONNECTED, {
socketId: socket.id,
username: userSocketMap[socket.id],
});
});
delete userSocketMap[socket.id];
socket.leave();
});
});
const PORT = process.env.PORT || 5001;
server.listen(PORT, () => console.log(`Listening on port ${PORT}`));

Unpacking BLOB from websocket

While using websocket, message that client gets is blob. Whats the best way to access its content? I have tried using FileReader but then it looked like {"user":"whatever","msg":"whatever"} and I would like to get it as {user:"whatever",msg:"whatever"}. Is it even possible?
const submitMessage = (usr, msg) => {
const message = { user: loggedInUser.username, message: msg };
ws.send(JSON.stringify(message));
setMessages([message, ...messages]);
}
useEffect(() => {
ws.onopen = () => {
console.log('WebSocket Connected');
}
ws.onmessage = (e) => {
const message = JSON.parse(e.data);
setMessages([message, ...messages]);
}
return () => {
ws.onclose = () => {
console.log('WebSocket Disconnected');
setWs(new WebSocket(URL));
}
}
}, [ws.onmessage, ws.onopen, ws.onclose, messages]);
**server**
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(data) {
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
});

Node websockets missing reason in close event

I'm developing a websocket server with Node.Js v14.17.3 using "ws": "^7.4.5" package.
My server code is this:
const WebSocket = require("ws");
const url = "localhost";
const port = 8081;
const wss = new WebSocket.Server({ host: url, port });
wss.on("connection", function (ws) {
ws.on("message", function (data) {
console.log("received: %s", data);
});
function onSocketClose(code, reason) {
console.log("Closing open web socket", code, reason);
console.log("Closed web socket.");
}
ws.on("close", onSocketClose);
});
My client code is this:
window.onclose = function (event) {
console.log("Window closing.");
closeSocket("Window closed");
};
window.onunload = function (event) {
console.info("Window unloaded");
closeSocket("Window unloaded");
};
function closeSocket(reason) {
if (reason) {
console.info("Closing socket due to:", reason);
} else {
reason = "Unknown reason";
}
webSocket.onclose = function (ev) {
console.info("Websocket closed.");
};
webSocket.close(1001, reason);
}
In server on("close", ...) callback I get an empty reason, while I'm expecting the reason I've specified in client method.

How to retry database connection in Node.js when first connect is failed?

I am using SQL Server with Node.js. When the connection fails in first attempt the Node.js does not reattempt to connect. I am using setTimeout() to keep trying periodically until it connects.
const poolPromise = new sql.ConnectionPool(config.db);
poolPromise
.connect()
.then(pool => {
console.log('Connected to MSSQL');
return pool;
})
.catch(err => {
if (err && err.message.match(/Failed to connect to /)) {
console.log(new Date(), String(err));
// Wait for a bit, then try to connect again
setTimeout(function() {
console.log('Retrying first connect...');
poolPromise.connect().catch(() => {});
}, 5000);
} else {
console.error(new Date(), String(err.message));
}
});
The above code attempt to connect, fails and try for second time but does not continue for third, fourth and so on.
I wrote this small snippet that works. I wrapped connection part into a function and then invoke it using a recursive function.
In this example you'll see an infinity.
function sql() {
this.connect = function() {
return new Promise((resolve, reject) => reject("error connecting"));
}
}
function connect() {
return new Promise((resolve, reject) => {
// const poolPromise = new sql.ConnectionPool("config.db");
const poolPromise = new sql();
poolPromise
.connect()
.then(pool => {
console.log("connected");
resolve(pool);
})
.catch(err => {
console.error(err);
reject(err);
});
});
}
function establishConnection() {
var a = connect();
a.then(a => console.log("success"))
.catch(err => {
console.error("Retrying");
// I suggest using some variable to avoid the infinite loop.
setTimeout(establishConnection, 2000);
});
};
establishConnection();
After checking out the answers here I agree that callbacks are the way to go. I wrote the follow script to attempt to connect to MySQL until connection is established, and then to occasionally check that the connection is still valid, and if not, attempt connection again. I placed console.log's in a few places so that as things run you can see and understand what's happening.
var mysql = require('mysql');
var env = require('dotenv').config()
// ENVIRONMENT LOADS
var env = process.env.NODE_ENV.trim();
var host = process.env.MYSQL_HOST.trim();
var user = process.env.MYSQL_USER.trim();
var password = process.env.MYSQL_ROOT_PASSWORD.trim();
var database = process.env.MYSQL_DB.trim();
var port = process.env.MYSQL_PORT.trim();
console.log('\n\n********\n\nMySQL Credentials\n\n********\n\n');
if (env != 'production') {
console.log("Host: ", host, ":", port);
console.log("User: ", user);
console.log("Database: ", database);
console.log("Password: ", password);
}else{
console.log('Using Production Credentials');
}
console.log('\n\n************************\n\n');
let mysqlDB = null; // db handler
let connected = null; // default null / boolean
let connectFreq = 1000; // When database is disconnected, how often to attempt reconnect? Miliseconds
let testFreq = 5000; // After database is connected, how often to test connection is still good? Miliseconds
function attemptMySQLConnection(callback) {
console.log('attemptMySQLConnection')
if (host && user && database) {
mysqlDB = mysql.createPool({
host: host,
port: port, // Modified for Dev env
user: user,
password: password,
database: database,
connectionLimit: 300,
waitForConnections: true, // Default value.
queueLimit: 300, // Unlimited
acquireTimeout: 60000,
timeout: 60000,
debug: false
});
testConnection((result) => {
callback(result)
})
} else {
console.error('Check env variables: MYSQL_HOST, MYSQL_USER & MYSQL_DB')
callback(false)
}
}
function testConnection(cb) {
console.log('testConnection')
mysqlDB.query('SELECT 1 + 1 AS solution', (error, results, fields) => {
try {
if (error) {
throw new Error('No DB Connection');
} else {
if (results[0].solution) {
cb(true)
} else {
cb(false)
}
}
} catch (e) {
// console.error(e.name + ': ' + e.message);
cb(false)
}
});
}
function callbackCheckLogic(res) {
if (res) {
console.log('Connect was good. Scheduling next test for ', testFreq, 'ms')
setTimeout(testConnectionCB, testFreq);
} else {
console.log('Connection was bad. Scheduling connection attempt for ', connectFreq, 'ms')
setTimeout(connectMySQL, connectFreq);
}
}
function testConnectionCB() {
testConnection((result) => {
callbackCheckLogic(result);
})
}
function connectMySQL() {
attemptMySQLConnection(result => {
callbackCheckLogic(result);
});
}
connectMySQL(); // Start the process by calling this once
module.exports = mysqlDB;

Categories