Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSockets Proxy using Socket.io-client in create-react-app

I'm trying to add a proxy to my react app for socket.io-client

I'm using setupProxy.js with http-proxy-middleware which works fine for APIs but not for sockets

Server code with node js

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function (socket) {
  setInterval(() => {
    console.log('emit event');
    io.emit('event', { data: 'worked successfully!' });
  }, 1000);
});

http.listen(8080, function () {
  console.log('listening on *:8080');
});

Client code with react

function App() {
  const socket = socketIOClient('/', {
    transports: ['websocket'],
  });

  useEffect(() => {
    socket.on('connect', () => {
      console.log('connected');
    });
    socket.on('event', (data) => {
      console.log(data);
    });

  }, []);
  return (
    <div className='App'>
     Socket Proxy test
    </div>
  );
}

and my setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = (app) => {
  app.use(
    '/socket.io',
    createProxyMiddleware({
      target: 'http://localhost:8080',
      changeOrigin: true,
      ws: true, // enable websocket proxy
      logLevel: 'debug',
    })
  );
};
like image 685
Chiller Avatar asked May 06 '20 23:05

Chiller


People also ask

How to implement socket in react app?

To implement socket in React application, we have to install socket.io-client npm package. It will help us to connect the socket using an endpoint. Run the following command to install the dependency. 3. Establish socket connection After successful installation, we have to start integration of the socket in the React app.

Can I integrate WebSockets into a React+Redux app?

Although using WebSockets is quite straightforward, integrating it into a React+Redux app can be tricky. This guide will use a practical example to explore different patterns of integrating WebSockets to a React app and discuss the pros and cons of each.

What is socket Io in WebSocket?

Socket.IO is a JavaScript library that provides a high-level API around WebSockets. This makes it easy to create real-time web applications with only a few lines of code. As an additional extra, Socket.IO falls back to a technique called long-polling in case a WebSocket connection can’t be established between the client and the server.

How do I use WebSocket in a real world application?

The WebSocket context can be accessed anywhere in the app using the useContext Hook, and all the included functionality will be available. Additionally, a real-world app would also need to handle the instances of socket disconnecting and reconnecting, and handling client exit.


1 Answers

I resolved the problem by adding custom path in both server and client socket options

{
  path: '/socket',
}

and then use that path in proxy middleware

  const socketProxy= createProxyMiddleware('/socket', {
    target: 'http://localhost:8080',
    changeOrigin: true,
    ws: true, 
    logLevel: 'debug',
  });

  app.use(socketProxy);

so final working code should look something like this :

Server code :

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http, {
  path: '/socket', // added this line of code
});

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function (socket) {
  setInterval(() => {
    console.log('emit event');
    io.emit('event', { data: 'worked successfully!' });
  }, 1000);
});

http.listen(8080, function () {
  console.log('listening on *:8080');
});

Client code :

function App() {
  const socket = socketIOClient('/', {
      transports: ['websocket'],
      path: '/socket', // added this line of code
  });

  useEffect(() => {
    socket.on('connect', () => {
      console.log('connected');
    });
    socket.on('event', (data) => {
      console.log(data);
    });

  }, []);
  return (
    <div className='App'>
     Socket Proxy test
    </div>
  );
}

Note: namespace should be added in <URL> param : const socket = socketIOClient('/namespace', {...})

and final setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = (app) => {
  const socketProxy= createProxyMiddleware('/socket', {
    target: 'http://localhost:8080',
    changeOrigin: true,
    ws: true, 
    logLevel: 'debug',
  });

  app.use(socketProxy);
};
like image 55
Chiller Avatar answered Oct 19 '22 21:10

Chiller