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',
})
);
};
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.
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.
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.
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.
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);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With