Friday 30 November 2018

ReactJS SocketIO bug or user error?

TLDR; When calling socket.emit inside of socket.on listener on the server, the emit is not received by react, but works in raw HTML.​I created a boilerplate example of this issue to try and nail down what is going on here. I have a simple server.js app that is running express and SocketIO on port 4001. I then created both a raw index.html page, and a simple react app (using create-react-app) to demonstrate the difference. Both have a button that sends a "test" emit to the server, and they listen for a "Hello World" from the server. When they receive "Hello World" from the server, they pop up a simple alert saying "Hello World Received." Interestingly enough, I only have an issue with this if I use socket.emit('Hello World') in the server-side socket.on('test') listener (specifically trying to send to the originating client). If I use io.emit('Hello World'), it works fine on both the html and react app. I have included snippets of my react App.js, the server.js node app, and the raw index.html. I have also zipped up the files here https://ift.tt/2PbvtwA so that someone can possibly verify what I am seeing.​To test, run npm install on both the main directory, and the socket-client subdirectory, run nodemon server.js from the main directory and run npm start from inside the socket-client subdirectory. As it is written, if you connect to localhost:3000 you will get the react app, and if you connect to localhost:4001 you will get the raw index.html.​In server.js, you can switch between io.emit and socket.emit by commenting out one of the two lines. The results of each are shown//io.emit('Hello World') //HTML: YES REACT: YES socket.emit('Hello World'); //HTML: YES REACT: NO If you go to localhost:3000, click on "Send Test Socket" button, you will not get an alert, despite the server getting the emit and sending the "Hello World" reply back, it's as if the client doesn't get the emitIf you go to localhost:4001, click on "Send" button, you will get an alert, which is what you'd expect from the server.js codeIf you go to server.js and edit lines 20-21 to uncomment io.emit and comment out socket.emit, suddenly both the react and index.html buttons work as expectedExtra: if you go to server.js and put a socket.emit('Hello World') on line 16 (inside the io.on('connection') listener), you will get the alert on both react and html versions, it's specifically an issue inside the socket.on() listenersBoth "clients" are pointing to the same server.js, so what is going on here? Am I doing something wrong with how I am listening on the react side somehow?​I hope this better documents the issue I am experiencing. Let me know if I can provide any further information.​​server.jsconst express = require('express') const http = require('http') const socketIO = require('socket.io') const port = 4001 const app = express() const server = http.createServer(app) const io = socketIO(server) app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); io.on('connection', socket => { console.log('New client connected') // just like on the client side, we have a socket.on method that takes a callback function socket.on('test', () => { console.log('Test socket received') //io.emit('Hello World') //HTML: YES REACT: YES socket.emit('Hello World'); //HTML: YES REACT: NO }) socket.on('disconnect', () => { console.log('user disconnected') }) }) server.listen(port, () => console.log(`Listening on port ${port}`)) ​App.js (react)import React, { Component } from "react"; import socketIOClient from "socket.io-client"; class App extends Component { constructor() { super(); this.state = { endpoint: "http://localhost:4001", }; } send = () => { const socket = socketIOClient(); socket.emit('test') // change 'red' to this.state.color } render() { // testing for socket connections const socket = socketIOClient(); socket.on('Hello World', () => { alert('Hello World Received') }) return (
) } } export default App; ​index.html
​https://getyarn.io/yarn-clip/fb2399f1-b88c-4001-9a56-3cfbfb1caa2a​​

Submitted November 30, 2018 at 10:46PM by Sintex

No comments:

Post a Comment