Aidenhsy
Aidenhsy

Reputation: 1591

Socket IO with React and Express Error: "WebSocket connection to '.......' failed: WebSocket is closed before the connection is established."

I am just learning socket IO and am trying to build the simplest chat application possible with create-react-app in the frontend and express in the backend.

After I set everything up and run both front and back at the same time, this error displays itself an infinite number of times in my browser: browser errors

I'm setting my frontend's proxy to my backend port. Would that be the problem?

Here is all my code, starting with the backend:

backend/index.js

const app = require('express')();
const server = app.listen(4000, () => {
  console.log('server listening on 4000');
});
const io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('message', (message) => {
    console.log(message);
    io.emit('message', `${message}`);
  });
});

frontend/App.js

import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';

function App() {
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState([]);
  const socket = io('/');
  useEffect(() => {
    socket.on('message', (data) => {
      setMessages([...messages, data]);
    });
  }, [messages, socket]);

  const sendHandler = () => {
    socket.emit(message);
  };
  return (
    <div>
      {messages.map((message) => (
        <ul>{message}</ul>
      ))}
      <input
        type="text"
        name="message"
        placeholder="message"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
      />
      <button onClick={sendHandler}>send</button>
    </div>
  );
}

export default App;

frontend/package.json

{
  "name": "frontend",
  "version": "0.1.0",
  "proxy": "http://127.0.0.1:4000",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.8",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.6.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "socket.io-client": "^3.0.5",
    "web-vitals": "^0.2.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Upvotes: 0

Views: 3013

Answers (2)

Seb
Seb

Reputation: 25147

The problem is you are creating the io() connection on every single render of your App, which can happen quite frequently. You need to create that connection only once outside App().

Upvotes: 0

lissettdm
lissettdm

Reputation: 13078

Store the socket client reference with useRef. This way you never loose the initial reference:

const socketRef = useRef(io('/'));
const socket = socketRef.current;

Upvotes: 1

Related Questions