user1144112
user1144112

Reputation: 611

What does "WebSocket is closed before the connection is established" mean?

I'm using JavaScript and the Union platform How would I go about diagnosing this problem? Many thanks.

Upvotes: 60

Views: 211517

Answers (5)

VityaSchel
VityaSchel

Reputation: 708

In React if you're writing some kind of App's wrapper component and connect to websocket in useEffect like so:

React.useEffect(() => {
  const ws = new WebSocket('ws://localhost:8001')    
  setWS(ws)

  return () => {
    ws.close()
  }
}, [])

this is due to React's strict mode intentional remounting of all components twice to help debug side effects, even if you have empty array of dependencies. See this question on Stackoverflow for more info

Solutions

  1. Turn off React's strict mode (either by removing <React.StrictMode> in ReactDOM.createRoot for example in Vite, or by settings reactStrictMode: false in config for example in Next.js)
  2. OR you can use React's refs since they are a simple way to manage state between renders:
const [ws, setWS] = React.useState<WebSocket | null>(null)
const wsRef = React.useRef<WebSocket | null>(null)

React.useEffect(() => {
  if (!wsRef.current || wsRef.current.readyState === WebSocket.CLOSED) {
    const ws = new WebSocket('ws://localhost:8001')
    wsRef.current = ws
    setWS(ws)
  }

  return () => {
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      wsRef.current.close()
    }
  }
}, [])

Upvotes: 2

Bambier
Bambier

Reputation: 846

In React you need to add this to your useEffect in return

useEffect(() => {
        const socket = new WebSocket(address);


        return () => {
            if (socket.readyState === 1) { // <-- This is important
                socket.close();
            }
        }
}, []);

However it not only the best solution! You need use hooks instead of using socket connection directly in view/component it can prevents multiple creation of socket connection.

Also socket connection should closed by backend if its not in use, whenever frontend is communicating or not.

Upvotes: 18

Ben Butterworth
Ben Butterworth

Reputation: 28532

In React, if you subscribe to websockets in useEffect, this error is fine when running in Strict Mode. React would create the subscription twice in Strict Mode, and the first 1 is thrown away immediately, be sure to close the first one!

The other react answer (by Bambier) is wrong...

...because it causes a memory leak. You end up with 2 subscriptions in React Strict mode (and local development). Why? It doesn't clean up the first subscription caused when the component renders twice. If the first component hasn't connected yet, you won't close it (socket.readyState === 1 is false). Eventually, the first WebSocket will eventually connect too.

This can also happen in production, when the component is re-rendered faster than the connection is formed. Your client and websocket server take longer to connect (larger distances/latencies), so this can definitely happen.

It hides the browser warning message, but adds a bug instead.

Upvotes: 11

BK NATANI
BK NATANI

Reputation: 9

Just open the port in server ufw enable

Upvotes: -6

leggetter
leggetter

Reputation: 15467

If you go to http://jsbin.com/ekusep/6/edit and view the JavaScript console you'll see the 'WebSocket is closed before the connection is established' logged. I've tested this in Chrome.

In this code what it means is that ws.close() was called (by user code) before the connection was even given a chance to be established.

So, the cause of this error is if code attempts to close the WebSocket connection before it's had a chance to actually connect.

Upvotes: 31

Related Questions