@Quod_42

Не получается отправить нужные данные по WebSocket?

на клиенте у меня есть класс для работы с Websocket:
class WebsocketsWork {
    constructor(headers) {
        this._allowedTypes = data.requests;
        this.ws            = new WebSocket("ws://localhost:3050", headers);
    }

	_waitForConnection(callback, interval) {
		if (this.ws.readyState === 1) {
			callback();
		} else {
			const that = this;

			// optional: implement backoff for interval here
			setTimeout(function () {
				that._waitForConnection(callback, interval);
			}, interval);
		}
	}

    /**
	 * Отправка сообщения на сервер
	 * @param {string} type Тип отправки
	 * @param {obj} payload Данные для отправки
	 * @public
	 */
	sendPayload(type, payload, callback) {
		if (!Object.values(this._allowedTypes).includes(type)) {
			throw new Error(`Такого типа для отправки не существует: ${type}`);
		}

		this._waitForConnection(() => {
			const obj = { type, payload };

			this.ws.send(JSON.stringify(obj));
			
			if (typeof callback !== "undefined") {
				callback();
			}
		}, 1000);
	}

	/**
	 * Соединение с сервером установлено
	 * @param {function} callback Функция, которая будет выполняться при соединении
	 * @public
	 */
	open(callback) {
		this.ws.addEventListener("open", (event) => { callback(event); });
	}

	/**
	 * Соединение с сервером закрыто
	 * @public
	 */
	close(callback) {
		this.ws.addEventListener("close", (event) => { callback(event); });
	}

	/**
	 * Соединение с сервером прервано ошибкой
	 * @param {function} callback Функция, которая будет выполняться при появлении ошибки
	 * @public 
	 */
	error(callback) {
		this.ws.addEventListener("error", (event) => { callback(event); });
	}

	/**
	 * Получение ответа от сервера
	 * @param {function} callback Функция, которая будет выполняться при получении ответа
	 * @public
	 */
	getAnswer(callback = function (data) { console.log(JSON.parse(data)); }) {
		this.ws.addEventListener("message", ({ data }) => {
			// Получение текущего типа отправки сообщения
			const { currentType, error, data: dataFromParse } = JSON.parse(data);
			
			if (error) {
                callback(error, null);
				return;
			}
			
			callback(null, { currentType, ...dataFromParse });
		});
	}
}

export default WebsocketsWork;


также есть отдельный объект с методами для отправки данных:
const permissions = {
    url      : "http://localhost:3050/api/permission",
    websocket: {
        ws: new WebsocketsWork(["access_token", cookie.get("token")])
    }
};

// Открываем соединение
permissions.websocket.ws.open(() => console.log("connected"));

/**
 * Добавление разрешения через websocket
 * @param {Object} payload Объект с данными
 * @param {Function} callback Функция обратного вызова для получения ответа
 */
permissions.websocket.add = function(payload, callback) {
    this.ws.sendPayload(data.requests.PERMISSIONS_ADD, payload, () => {
        this.ws.getAnswer((error, res) => {
            if (res.currentType !== data.requests.PERMISSIONS_ADD) {
                return callback(null, null);
            }

            callback(error, res);
        });
    });
}

/**
 * Получение разрешений через websocket
 * @param {Object} payload Объект с данными
 * @param {Function} callback Функция обратного вызова для получения ответа
 */
permissions.websocket.getAll = function(payload, callback) {
    this.ws.sendPayload(data.requests.PERMISSIONS_GET_ALL, payload, () => {
        this.ws.getAnswer((error, res) => {
            if (res.currentType !== data.requests.PERMISSIONS_GET_ALL) {
                return callback(null, null);
            }

            callback(error, res);
        });
    });
}


я импортирую этот файл на страницу с кнопкой отправления и применяю метод add:
import permissions from "../permissions.js";

btn.addEventListener("click", () => {
permissions.websocket.add(payload, (error, result) => {
            if (result === null) return;
            if (error) {
                alert.error(error);
                loader.hide();
                console.error(error);
                return;
            }

            const { success, errors, message, error: serverError, permission } = result;
...

});


на стороне сервера вызываю контроллер в главном index.js файле:
const app    = express();
const server = http.createServer(app);
const wss    = new WebSocket.Server({ server });

// Обработка websocket соединений
new PermissionsControllerWebsocket(wss);


вот так выглядит PermissionsControllerWebsocket:
class PermissionControllerWebsocket {
    constructor(wss) {
        this.wss = wss;
        this.initialize();
    }

    initialize() {
        this.wss.on("connection", (ws, req) => {
            try {
                console.log("new connection");

                this.add(ws, req);
            } catch(error) {
                Logger.error(`PermissionsWebsocketController.initialize: ${error}`, 500);
            }
        });
    }

add(ws, req) {
        ws.on("message", async (message) => {
            const data = JSON.parse(message);

            if (data.type === "PERMISSIONS_ADD") {
                // code...
                const resultToSend = { currentType: "PERMISSIONS_ADD", payload };

                ws.send(JSON.stringify(resultToSend)); // Отправляем информацию о том, что все добавилось

                const resultToModerator = { currentType: "PERMISSIONS_GET_ALL", ...resultToSend }; 
                
                this.wss.clients.forEach((client) => {
                    if (client !== ws && client.readyState === require("ws").OPEN) {
                        client.send(JSON.stringify(resultToModerator)); // Отправляем информацию отдельному клиенту, который постоянно ожидает новые данные (resultToSend)
                    }
                });
            }
        });
    }
}


на странице ожидания новых данных такая логика:
import permissions from "../permissions.js";
permissions.websocket.getAll({ l: 5, o: 0 }, (error, data) => {
    if (data === null) return;

    // code ...
});


прикол в том что я не получаю на странице ожидания PERMISSIONS_GET_ALL нужный тип с данными, мне приходит PERMISSIONS_ADD, почему так?
  • Вопрос задан
  • 271 просмотр
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
const resultToSend = { currentType: "PERMISSIONS_ADD", payload };
const resultToModerator = { currentType: "PERMISSIONS_GET_ALL", ...resultToSend };

При деструктуризации resultToSend свойство currentType будет заменено.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы