简体   繁体   中英

What is best practice to websocket reconnect in react?

I have react app with ticket polling (ticket is part of link for websocket connection). Then I pass websocket object to another component, because only this (another) component should make .send() After user login or logout I need to get new ticket for new connection because server has specialized data for logged users. How should I organize my code for this task?

I tried to reassign ws object after login/logout but got "Assignments to the 'ws' variable from inside React Hook useEffect will be lost after each render" error I can't store ws assignment inside useEffect hook because then i not be able to pass it as prop I'm although using Redux as you can see

const App = () => {
  const { ticket, isLoggedIn } = useSelector(state => state);
  const dispatch = useDispatch();

  useEffect(() => {
    const requestTicket = () => {
      fetch('http://some/api/websocket', {
        method: 'POST'
      })
        .then(response => response.json())
        .then(ticket => {
          dispatch(setTicket(ticket));
        });
    };
    requestTicket();
  }, [dispatch]);

  let ws = new WebSocket('ws://socket/' + ticket);

  useEffect(() => {
    fetch('http://some/api/websocket', {
      method: 'POST'
    })
      .then(response => response.json())
      .then(ticket => {
        ws = new WebSocket('ws://socket/' + ticket);
      });
  }, [isLoggedIn, ws]);

  ws.onmessage = e => {
    dispatch(setData(JSON.parse(e.data)));
  };

  return <Child ws={ws} />;
};

Wrap WebSocket connection and onmessage in a function. check if WebSocket is close, callback the function. Also may use setTimeout. Example:

function connect(){
  //WebSocket Connection
  //WebSocket onmessage
}
conn.onclose = evt => {
console.log('Socket is closed.Reconnect will be attempted in 10 second.', evt.reason);
    setTimeout(() => connect(), 10000);
};

I'm using this way

function connect() {
  var ws = new WebSocket('ws://localhost:8080');
  ws.onopen = function() {
    // subscribe to some channels
    ws.send(JSON.stringify({
        //.... some message the I must send when I connect ....
    }));
  };

  ws.onmessage = function(e) {
    console.log('Message:', e.data);
  };

  ws.onclose = function(e) {
    console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
    setTimeout(function() {
      connect();
    }, 1000);
  };

  ws.onerror = function(err) {
    console.error('Socket encountered error: ', err.message, 'Closing socket');
    ws.close();
  };
}

connect();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM