I'm using socket.io-redis and it doesn't seem like it's connected... I tried with my client application and with socketio-client-tool, but I'm not getting any connections. here's my code:
index.js
const express = require('express');
const app = express();
const server = require('http').createServer(app);
require('./socket/socket')(server);
module.exports = server.listen(4000, () => logger.info(`Listening on port 4000`));
socket.js
module.exports = function (server) {
const _io = io(server);
const redisConnection = redisAdapter({ host: 'localHost', port: 6379 });
logger.info('connected to redis');
_io.adapter(redisConnection);
logger.info(`connected to socket.io`);
_io.on('connection', (socket) => {
console.log('a user connected');
});
};
I'm using ngrok to access the backend. Not sure if that has to do...
Related
After implementing the scaling code in my app with Redis the receipt at the client-side was unable to receive the emits from the socket server.
I tried using the sample code in the following package page
https://www.npmjs.com/package/#socket.io/redis-adapter
read the inspiration concept from the given example
https://medium.com/containers-on-aws/scaling-a-realtime-chat-app-on-aws-using-socket-io-redis-and-aws-fargate-4ed63fb1b681
The library used in this was deprecated, so I took the new version of the library and tried the code.
I have attached the code used for the app
const app = express();
const { createClient } = require('redis');
const redisAdapter = require('#socket.io/redis-adapter');
const server = require('http').createServer(app);
const io = require('socket.io')(server);
app.get('/', (req, res) => {
const arr = Array.from(io.sockets.adapter.rooms);
const filtered = arr.filter(room => !room[1].has(room[0]));
const rooms = filtered.map(i => (i[0]));
res.send({ rooms });
});
let pubClient;
(async () => {
pubClient = createClient({ host: 'localhost', port: 6379 });
pubClient.on('error', (err) => console.log('Redis Client Error', err));
await pubClient.connect();
const subClient = pubClient.duplicate();
io.adapter(redisAdapter(pubClient, subClient));
})();
// const pubClient = createClient({ host: 'localhost', port: 6379 });
io.on('connection', (socket) => {
socket.on('join', (room) => {
socket.join(room)
console.log(`Room to be joined ${room}`);
console.log(io.sockets.adapter.rooms);
console.log(io.sockets.adapter.sids);
})
socket.on('message', (message) => {
console.log(message)
const status = socket.emit(message.to, message.content)
console.log(status)
})
});
const port = 3000
server.listen(port, () => {
console.log(`Server listening to port ${port} with process id ${process.pid}`);
});```
Iam not sure if I miss some thing while scaling the app.Please do share your idea on this.
I am creating a web application, using socket.io . A Server error occurred while connecting to the server. We found out that the error is in the backend. What could be written incorrectly here? Code:
const path = require('path');
const express = require('express');
const app = express();
const fs = require("fs");
var privateKey = fs.readFileSync('path').toString();
var certificate = fs.readFileSync('path').toString();
const http = require('https').Server({key:privateKey,cert:certificate}, app);
const io = require('socket.io')(http);
const port = 9998;
const debug = true;
var connectedArray = new Array()
const delay = 60 * 1000
const mysql = require('mysql2');
const db = mysql.createConnection({
host: 'localhost',
user: 'user_name',
password: 'user_password',
database: 'database',
});
io.on('connection', (socket) => {
socket.on('register', msg => {
console.log("User registered")
connectedArray.push({
connectmessage: msg,
socket: socket,
})
})
socket.on('disconnect', () => {
if (debug) console.log('User disconnected')
})
})
app.use(express.static(path.resolve(__dirname, 'static')))
app.get('/', (req, res) => {
res.sendFile('./index.html')
})
http.listen(port, () => {
console.log(`Server started listening on port ${port}...`)
})
P.S: The problem began to arise after binding the domain
P.S 2: I have two sites on server, on different Apache virtual hosts
P.S 3: I am using https
how to use PeerServer deployed on heroku, in react native
I watched a youtube tutorial where tutor connected his react-native app with peerserver on localhost:5000 and that worked. However, my peerserver is deployed on heroku, trying to connect my app to it the same way the tutor did isn't working. I get the error [Error: Could not get an ID from the server.] which comes from peerServer.on('error', console.log)
This is my react-native code
export const API_URI = 'https://mvmserver.herokuapp.com'
// Peer Config
const peerServer = new Peer(undefined, {
host: 'mvmserver.herokuapp.com',
secure: false,
port: 52129,
path: '/mypeer'
})
peerServer.on('error', console.log)
// Socket config
export const socket = IO(`${API_URI}`, {
forceNew: true
})
socket.on('connection', () => console.log('Connected client'))
This is how the tutor had his
export const API_URI = 'localhost:5000'
// Peer Config
const peerServer = new Peer(undefined, {
host: '192.00.0.0.0',
secure: false,
port: 5000,
path: '/mypeer'
})
peerServer.on('error', console.log)
// Socket config
export const socket = IO(`${API_URI}`, {
forceNew: true
})
socket.on('connection', () => console.log('Connected client'))
My peerserver.js on heroku
const express = require('express')
const http = require('http')
const socketio = require('socket.io')
const {ExpressPeerServer} = require('peer');
const app = express();
const server = http.createServer(app)
const io = socketio(server).sockets
//Borderparser
app.use(express.json())
const customGenerationFunction = () => (Math.random().toString(36) + "0000000000000000000").substr(2, 16)
const peerServer = ExpressPeerServer(server, {
debug: true,
path: '/',
genderateClientId: customGenerationFunction
})
app.use("/mypeer", peerServer)
io.on('connection', function(socket) {
console.log('connected')
socke.on('join-room', ({roomID, userId}) => {
socket.join(roomID)
socket.to(roomID).broadcast.emit('user-connected', userId)
})
})
const port = process.env.PORT || 5000
server.listen(port, () => console.log(`Server is running on port ${port}`))
i am new to socket.io and i can't get it to connect to react app. here is my app.js in node
const express = require('express');
const port = process.env.PORT || 4000;
const router = require('./routes/routes');
const cors = require('cors');
const app = express();
const bodyParser = require('body-parser');
const db = require('./db/db');
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => {
console.log('connected');
});
app.use('*', cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
(router);
app.listen(port, () => {
console.log('listening on port ' + port);
db.sync({
// force: true,
logging: false,
});
});
and my front end code.
import React, { useState, useEffect, useRef } from 'react';
import { io } from 'socket.io-client';
import classes from './Chatroom.module.css';
const Chatroom = ({ user, getAllMessages, setGetAllMessages }) => {
const ENDPOINT = 'http://localhost:4000/getallmessages';
var socket = io(ENDPOINT);
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
socket.on('connect', () => {
socket.send('hello');
console.log('connected.');
});
console.log(socket);
}, []);
Whenever i look in the console on it shows connected: false and nothing is logging on the backend.
In order to fix the issue i had to add options to my io declaration as follows.
const server = require('http').createServer(app);
const options = {
cors: true,
origins: ['http://127.0.0.1:3000'],
};
const io = require('socket.io')(server, options);
127.0.0.1 being home and on client side my server is on 3000 so that's where that comes from. and on the client side you were right i had to remove "getallmessages" route so now it is as follows.
onst ENDPOINT = 'http://localhost:4000/';
var socket = io(ENDPOINT);
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
socket.on('connect', () => {
socket.send('hello');
console.log('connected.');
});
console.log(socket);
}, []);
socket.io is bound to the server object so you should listen to the server instead of the app.
Change app.listen to server.listen
Change endpoint by removing getallmessages if you are not using namespaces
I have a really simple NodeJS app that I want to run on Heroku. This is how the index.js file looks like:
Server (port 3030)
const http = require('http');
const os = require('os');
const express = require('express')
const throng = require('throng'); // For cluster management
const { port, env, isProduction } = require('./config/vars');
const SocketIO = require('socket.io');
// Setting up a simple express app and wrapping it with http server
const setupServer = () => {
const app = express();
app.use(express.static(path.join(__dirname, '../public')));
const server = http.createServer(app);
return server;
};
const setupSocket = (server) => {
const io = new SocketIO(server);
io.on('connection', (socket) => {
console.log(`[Socket] Connection established: ${socket.id}`);
socket.on(msg.rooms.join, (room) => {
socket.join(room);
socket.to(room).emit(msg.rooms.joined);
console.log(`[Socket] User ${socket.id} joined '${room}' room`);
});
socket.on('disconnect', () => {
console.log(`[Socket] Distonnected: ${socket.id}`);
});
});
return io;
};
const WORKERS = (() => {
if (!isProduction) return 1;
return process.env.WEB_CONCURRENCY || os.cpus().length;
})();
async function master() {
console.log(`Preparing ${WORKERS} workers...`);
console.log('Master started.');
}
// There should be one server instance for each worker
const start = () => {
const server = setupServer(); // Returns and `http` server instance
const socket = setupSocket(server);
server.listen(port, async () => {
Logger.info(`Server – listening on port ${port}`);
});
return server;
};
const instance = throng({
workers: WORKERS,
lifetime: Infinity,
start,
master,
});
module.exports = instance;
Client (port 3000)
const setupSocket = ({ room }) => {
// Fallback if already setup
if (window.sockets[room]) {
return window.sockets[room];
}
const socket = io('http://localhost:3030');
socket.on('connect', () => {
console.log('[Socket] Connection established!', socket.id);
socket.emit('room.join', room);
});
socket.on('room.joined', () => {
console.log(`[Socket] Connected to ${room} room!`);
});
window.sockets[key] = socket;
return socket
};
The problem – the connection is sometimes established properly but most of the time I get an error
Error during WebSocket handshake: Unexpected response code: 400
What might be the problem here? Is it because I have it on two different ports or is it because of the clusters?
I've tried removing the throng part of the code, and just calling start() method without any cluster setup, but the problem remains :(
why would you use http module? The server instance that you send in the socketIO constructor should be the return object of the expressInstance.listen
Something more like this:
const express= require('express')
const app = express()
const socketio = require('socket.io')
app.use(express.static(__dirname + '/public'))
const server = app.listen('4000',()=>{
console.log('Listening to port:4000')
})
const io = socketio(server)
io.on('connect',(socket)=>{
socket.broadcast.emit('new_user')
socket.on('new_message',(message)=>{
io.emit('new_message',message)
})
})
source code: socket-io chat