Как создать один веб-сокет на все потоки?

Поддержка
  • Пытаюсь сделать, чтобы при запуске шаба открывалось одно соединение, уходило сообщение на сервер в ws.on с запросом на авторизацию. Ну а следующие сообщения, чтобы выполнялись в потоках где нужно их вызывать.

    Предвосхищая вопросы, у сервиса в API ограничение на 3 одновременных клиента с одного IP. Можно через прокси легко решить проблему, но хотелось бы понять как вообще это сделать с помощью одного клиента.

    Попробовал так, не работает.

    В onApplicationStart:

    const WebSocket = require('ws');
    global.ws = new WebSocket('wss://s.2captcha.com/');
    

    В потоках:

    const uuid = require('uuidv4');
    
    const request_id = uuid.uuid();
    var cookies_arr = JSON.stringify(
        JSON.parse( [[COOKIES]] ).cookies
    );
    
    function ws_run(){
        return new Promise((resolve, reject) => {
            global.ws.on('open', () => {
                global.ws.send(JSON.stringify(
                    {
                        method: 'auth',
                        key: [[RUCAPTCHA_KEY]],
                        requestId: request_id
                    }
                ))
                resolve('connected');  	
            });
    
            global.ws.on('close', () => {
                reject('disconnected');  
            });
        });
    }
    
    await (new Promise((resolve, reject) => {
        var promise = ws_run();
        var i = 1
        promise
        .then(res=>{
            global.ws.on('message', (m) => {
                var msg = JSON.parse(m);
                if (msg.method == 'auth' && msg.requestId == request_id) {
                    console.log(`${i}: auth`)
                    console.log(msg)
                    if (!msg.success) {
                        reject(`Ошибка авторизации в rucaptcha: ${msg.error}`);
                    }
    
                    global.ws.send(JSON.stringify(
                        {
                            method: 'funcaptcha',
                            requestId: request_id,
                            sitekey: `...`,
                            url: `...`,
                            options: {
                                ...
                            },
                            proxy: {
                                ...
                            }
                        }
                    ))
                } else if (msg.method == 'funcaptcha') {
                    console.log(`${i}: funcaptcha`)
                    console.log(msg)
                    if (!msg.success) {
                        reject(`Капча не принята сервером: ${msg.error}`);
                    } else {
                        console.log(`Rucaptcha ID: ${msg.captchaId}`)
                        [[CAPTCHA_ID]] = msg.captchaId;
                    }
                } else if (msg.method == 'solution') {
                    console.log(`${i}: solution`)
                    console.log(msg)
                    if (!msg.success) {
                        reject(`Не удалось решить капчу: ${msg.error}`);
                    } else {
                        if (msg.code == 'ERROR_CAPTCHA_UNSOLVABLE') {
                            reject(`Не удалось решить капчу, ID: ${msg.captchaId}`);
                        } else {
                            console.log(`Решили капчу, ID: ${msg.captchaId}`)
                            [[CAPTCHA_CODE]] = msg.code;
                            resolve()
                        }
                    }
                }
                i += 1
            }),
            err=>{
                console.log(err);
                reject();
            };
        });
    }));
    
  • @thepappo в onApplicationStart по идее надо вынести весь код который касается авторизации, а в потоках только отправлять и принимать сообщения

  • @UserTrue не пойму как это сделать. Из onApplicationStart такое ощущение что в потоках переменные просто нода не видит. Т.к. даже в коннект не попадает. И при этом никакие ошибки не выводятся.

  • @thepappo все прекрасно видит, решал подобные задачи