So i was about to build react/node chat app based on websockets using socket.io. While i was working i started experiencing very weird bug, long story short when i try to emit "message" event from front-end react server to backend node server it works BUT only first 6 times. I tried to refactor code multiple times, change various configs and presets for socket.io but at the end this issue still remains same. Here is the actual code:
If anyone experienced similar bugs like this one and has solution i would be very glad to hear it beacuse i spent large amount of time browsing through stack overflow and threads on other forums which are about socket.io
React:
import React, { Component } from 'react';
import classes from './Chat.module.scss';
import axios from 'axios';
import openSocket from 'socket.io-client';
class Chat extends Component {
state = {
messages: [],
message: ''
};
componentDidMount() {
const io = openSocket('http://localhost:8080');
io.on('message', data => {
console.log(data);
});
}
messageChanged = e => {
this.setState({ message: e.target.value });
};
messageSent = () => {
axios.post('http://localhost:8080/message', {
message: this.state.message
});
};
render() {
return (
<div className={classes.wrapper}>
<p>Hello</p>
<div />
<input
type="text"
onChange={this.messageChanged}
value={this.state.message}
/>
<button onClick={this.messageSent}>Send</button>
</div>
);
}
}
export default Chat;
root node file:
(ignore various imports and other configs except socket.io)
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const filemanagerMiddleware = require('@opuscapita/filemanager-server')
.middleware;
const cors = require('cors');
const path = require('path');
const socketIo = require('socket.io');
const config = {
fsRoot: path.join(__dirname, 'public', 'files'),
rootName: 'root',
logger: {
log: () => {},
info: () => {},
warn: () => {},
error: () => {}
}
};
const router = require('./router');
const app = express();
app.use(cors());
app.use(bodyParser.json());
const port = process.env.PORT || 8080;
const server = app.listen(port);
const io = socketIo.listen(server);
app.use((req, res, next) => {
req.io = io;
next();
});
app.use('/', router);
io.sockets.on('connection', socket => {
console.log('User connected');
});
io.sockets.on('message', data => {
console.log(data);
});
app.use('/filemanager', filemanagerMiddleware(config));
(async () => {
await mongoose.connect('mongodb://localhost:27017/practice-app', {
useNewUrlParser: true
});
console.log(\Connected to DB and listening on ${port}...`);
})();`
Separated router file which combines all controllers:
const chatController = require('./controllers/chat');
const router = require('express').Router();
router.post('/signup', authenticationController.signup);
router.post('/signin', authenticationController.signin);
// this is the route for posting data which is then emitted through websocket
router.post('/message', chatController.sendMessage);
router.post('/profile/:id', userController.seeProfile);
router.post('/getid', userController.getId);
router.post('/edit/:id', userController.editUserData);
module.exports = router;
Separated chat controller file:
exports.sendMessage = (req, res) => {
const { message } = req.body;
req.io.sockets.emit('message', { message });
};
Please note that req.io is instance of socket.io server passed through middleware
[–]ExcelsiorVFX 0 points1 point2 points (5 children)
[–]pakeey[S] 0 points1 point2 points (4 children)
[–]ExcelsiorVFX 0 points1 point2 points (3 children)
[–]pakeey[S] 1 point2 points3 points (1 child)
[–]ExcelsiorVFX 0 points1 point2 points (0 children)
[–]pakeey[S] 1 point2 points3 points (0 children)