I'm trying to configure websockets through http-proxy-middleware. I'm using Docker with NodeJS and React with react-create-app.
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use('/api/v4/', createProxyMiddleware({ target: 'http://drf:8081', changeOrigin: true}));
app.use('/api/v4/ws/users/', createProxyMiddleware({ target: 'ws://asgi-server:8082', changeOrigin: true, ws: true}));
};
socket-service.ts
import React from 'react';
interface Props {
cookies: any;
page: any;
address: any;
}
interface requestFormatRPC {
method: string;
params: {[key: string]: any};
id: string;
}
interface responseFormatRPC {
result: any;
error: any;
id: string;
}
export const socketService = (data: Props) => {
const wsProtocol = window.location.protocol === 'http:' ? 'ws:' : 'wss:';
const webSocket = new WebSocket(
`${wsProtocol}//${window.location.host}/api/v4/ws/users/`
);
};
export class webSocketService {
webSocket: any = null;
subscribers: any = {};
sessionId: any = null;
constructor() {
//...
}
private addListeners(self = this) {
console.log('ADD LISTENERS START');
this.webSocket.onmessage = function (event: { [key: string]: any }) {
const data = JSON.parse(event.data);
self.notifySubscribers(data.event, data.data);
};
this.webSocket.onopen = function () {
let sessionCookie = document.cookie.replace(
/(?:(?:^|.*;\s*)session_id\s*\=\s*([^;]*).*$)|^.*$/,
'$1'
);
self.sessionId = sessionCookie ? sessionCookie.split('|')[4].split(':')[1] : null;
console.log(self.sessionId);
self.notifySubscribers('onopen', {});
};
}
private notifySubscribers(event: string, data: any) {
const list = this.subscribers[event];
if (list) {
list.forEach((el: any) => {
el.callback(event, data);
});
}
}
connect() {
if (!this.webSocket) {
console.log('CONNECT WS START');
const wsProtocol = window.location.protocol === 'http:' ? 'ws:' : 'wss:';
this.webSocket = new WebSocket(
`${wsProtocol}//${window.location.host}/api/v4/ws/users/`
);
this.addListeners();
}
}
subscribe(events: any[], callback: any) {
if (events && events.length && callback) {
events.forEach((event: any) => {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.subscribers[event].push({
event: event,
callback: callback,
});
});
}
}
send(event: any, data: any) {
if (event && data && this.sessionId) {
this.webSocket.send(
JSON.stringify({ event, data, session: this.sessionId })
);
}
}
}
But it only works for my api drf. For websockets Google and Firefox sends error: WebSocket connection to 'ws://localhost:7000/api/v4/ws/users/' failed:
I tried to add WDS_SOCKET_PORT=0 in env and docker-compose.yml, but nothing helps I set it up with Nginx for production, but i have no understanding how to do it locally with React
I just figured it out by editing http-proxy-middleware
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api/v4/',
createProxyMiddleware({
target: 'http://drf:8081',
changeOrigin: true,
})
);
app.use(
createProxyMiddleware('/api/v4/ws/', {
target: 'http://asgi-server:8082',
changeOrigin: true,
ws: true,
})
);
};
It's a bit different and i do not understand the changes, but it works. I find the solution here Link