0

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:

Google Error

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

1 Answer 1

0

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

Sign up to request clarification or add additional context in comments.

1 Comment

it looks like you changed original /api/v4/ws/users/ to /api/v4/ws/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.