Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20

WebSocket ответы для пользователя

03.12.2020, 18:26. Показов 1413. Ответов 11

Студворк — интернет-сервис помощи студентам
Выручайте *О* что-то пошло не так как я предполагал. Создал я значт сервер на веб сокете. Библиотека "ws". Подключаюсь на клиенте (Первый пользователь) - ответы получаю хорошо, подключаюсь (вторым пользователем) и теперь первый пользователь перестает получать ответы. при любом запросе на сервер ответы за него получает второй пользователь. Можно ли как то изолировать пользователей друг от друга? уже голову сломал.
Вот код создания сервера и прослушивания событий.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
this.id= null;
this.matchId = 0;
this.wss = new WebSocket.Server({ server:app });
 
this.wss.on('connection', (ws) => {
      this.id =  this.matchId = this.matchId + 1; //
      clientsArr.push(ws);
      console.log("Подключение. Пользователей онлайн: "+clientsArr.length);
      this.ws = ws;
      this.ws.on('message', (data) => {
          this.parse(data); // слушаем события сокета
      })
      this.ws.on('close', ()=>{
          this.active = false;
          for(var i=0, l=clientsArr.length; i<l; i++) {
              if(this.ws == clientsArr[i]) {
                  clientsArr.splice(i,1);
                  console.log("Отключение. Пользователей онлайн: "+clientsArr.length);
                  break;
              }
          }
      });
})
а вот так отправляю ответы клиенту
JavaScript
1
clientsArr[this.id].send("Тут крч ответ.")
если допустим у первого пользователя id = 1. Подключается второй пользователь, id становится уже =2. и значит ответы все будут идти только второму пользователю...((
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.12.2020, 18:26
Ответы с готовыми решениями:

Считать ответы пользователя и добавить ответы в список
Пишу программу, которая считывает ответы пользователя и по полученным ответам выводит результат. Программа - бестиарий, т.е....

Идентификация пользователя в WebSocket
Есть ли у WebSocket возможность идентификации пользователя при подключении. Допустим, пользователь ставит лайк какой-то записи. Обязательно...

Аутентификация пользователя в WebSocket-ах на Spring Boot 2 + SockJS
Использовал этот гайд. Но вот столкнулся с тем что мне нужно получить юзера в контроллере. А получить его я могу из JWT токена. Если с...

11
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
03.12.2020, 21:47
Нужно пробежаться по списку подключённых клиентов и отослать каждому сообщение:

public/index.html

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Client</title>
</head>
 
<body>
    <button id="btnSend">Click to send "Hello"</button>
    <div id="output" style="font-family: Arial; font-size: 14px;"></div>
 
    <script>
        const btnSend = document.getElementById("btnSend");
        const output = document.getElementById("output");
        output.innerHTML = "Wait for connection...";
        const ws = new WebSocket("ws://localhost:3000");
        ws.onopen =
            () => {
                output.innerHTML = "Connected to the server";
                btnSend.onclick = (event) => {
                    ws.send(JSON.stringify({request: "Hello"}));
                };
 
                ws.onmessage = (event) => {
                    console.log(event.data);
                    const msg = JSON.parse(event.data);
                    output.innerHTML = `Answer from server: ${msg.response}`;
                }
            };
    </script>
</body>
 
</html>


app.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const express = require("express");
const http = require("http");
const ws = require("ws");
const path = require("path");
 
const app = express();
app.use(express.static(path.join(__dirname, "./public")));
app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
 
const httpServer = http.createServer(app);
const wss = new ws.Server({ server: httpServer });
let counter = 0;
wss.on("connection",
    (ws) =>
    {
        console.log("Client connected");
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data).request;
                console.log(msg);
                wss.clients.forEach((client) => {
                    client.send(JSON.stringify({ response: msg + ": " + counter}));
                });
                counter++;
            }
    });
 
const port = process.env.PORT || 3000;
httpServer.listen(port, () => { console.log("Server started. Port: ", port); });


Книжный пример Крестиков-ноликов на WebSockets: https://github.com/formigone/h... ic-tac-toe Из книги: Multiplayer Game Development with HTML5
1
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20
04.12.2020, 08:27  [ТС]
Цитата Сообщение от 8Observer8 Посмотреть сообщение
отослать каждому сообщение
А если мне нужно отправить ответ только тому пользователю который запросил?
В этом и проблема что я не могу целенаправленно прислать пользователю ответ на его, к примеру "какой у меня уровень?". Если подключается другой пользователь, то он и получает все данные за первого...
0
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
04.12.2020, 09:54
Для примера, пусть у каждого пользователя своё имя и он запрашивает это имя. Для генерации имени поставим пакет shortid:
npm i shortid
При подключении подключении клиента выводим его имя в консоль и сохраняем это имя в виде параметра ws.id. Когда приходит запрос от клиента "get_id", то высылаем клиенту его id в посылки с названием "my_id":

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wss.on("connection",
    (ws) =>
    {
        ws.id = shortId.generate();
        console.log("Client connected. id = " + ws.id);
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data);
                console.log(msg);
                if (msg.action === "get_id")
                {
                    ws.send(JSON.stringify({ action: "my_id", id: ws.id }));
                }
            };
    });
На клиенте будет отправлять запрос "get_id" по нажатию на кнопку и будем готовы принять посылку "my_id", чтобы вывести свой id на экран:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        ws.onopen =
            () => {
                output.innerHTML = "Connected to the server";
                btnSend.onclick = (event) => {
                    ws.send(JSON.stringify({ action: "get_id" }));
                };
 
                ws.onmessage = (event) => {
                    const msg = JSON.parse(event.data);
                    console.log(msg);
                    if (msg.action === "my_id")
                    {
                        output.innerHTML = `My id: ${msg.id}`;
                    }
                }
            };
Результат на сервере:

Server started. Port: 3000
Client connected. id = U2Ex_tYzd
{ action: 'get_id' }
Client connected. id = G4_zMJz3g
{ action: 'get_id' }
Каждый клиент получил свой id:

Название: 8c7449ba-4995-45aa-ba42-0f0d25b23200.png
Просмотров: 86

Размер: 1.2 Кб

Название: ef67acfd-e505-44d8-b02d-e80da905d7f9.png
Просмотров: 83

Размер: 1.3 Кб

public/index.html

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Client</title>
</head>
 
<body>
    <button id="btnSend">Click to get my id</button>
    <div id="output" style="font-family: Arial; font-size: 14px;"></div>
 
    <script>
        const btnSend = document.getElementById("btnSend");
        const output = document.getElementById("output");
        output.innerHTML = "Wait for connection...";
        const ws = new WebSocket("ws://localhost:3000");
        ws.onopen =
            () => {
                output.innerHTML = "Connected to the server";
                btnSend.onclick = (event) => {
                    ws.send(JSON.stringify({ action: "get_id" }));
                };
 
                ws.onmessage = (event) => {
                    const msg = JSON.parse(event.data);
                    console.log(msg);
                    if (msg.action === "my_id")
                    {
                        output.innerHTML = `My id: ${msg.id}`;
                    }
                }
            };
    </script>
</body>
 
</html>


app.js
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const express = require("express");
const http = require("http");
const ws = require("ws");
const path = require("path");
const shortId = require("shortid");
 
const app = express();
app.use(express.static(path.join(__dirname, "./public")));
app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
 
const httpServer = http.createServer(app);
const wss = new ws.Server({ server: httpServer });
wss.on("connection",
    (ws) =>
    {
        ws.id = shortId.generate();
        console.log("Client connected. id = " + ws.id);
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data);
                console.log(msg);
                if (msg.action === "get_id")
                {
                    ws.send(JSON.stringify({ action: "my_id", id: ws.id }));
                }
            };
    });
 
const port = process.env.PORT || 3000;
httpServer.listen(port, () => { console.log("Server started. Port: ", port); });
1
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20
04.12.2020, 10:31  [ТС]
Скажите пожалуйста, т.е. нужно к любому запросу на сервер цеплять уникальный идентификатор с клиента что бы сервер мог понять кому сейчас он ответит?
0
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
04.12.2020, 10:46
Сервер не знает ничего об идентификаторе. Можно назвать по-другому, например, ws.client_id. Переменная "ws" на сервере для каждого клиента своя личная.
1
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20
04.12.2020, 11:17  [ТС]
Я тоже так предполагал что у каждого свое соединение, но почему то ответы которые предназначены для первого пользователя, получает второй. Влияет ли на это то что я сохраняю в переменную для последующего обращения к ней, для отправки через нее ответа на клиент:
JavaScript
1
2
3
4
5
6
7
8
this.wss = new WebSocket.Server({ server:app });
this.wss.on('connection', (ws) => {
   console.log("Подключился пользователь");
   this.ws = ws;
   ws.on('message', (data) => {
       this.parse(data);
   })
})
Просто логика скажем так, реагирования сервера на запросы клиента вынесена у меня в отдельный класс, и оттуда посылаются ответы.
0
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
04.12.2020, 12:02
Цитата Сообщение от beardyman999 Посмотреть сообщение
this.ws = ws;
Здесь ошибка. Удалите эту строку. this.ws - это общая переменная. Каждый следующий клиент будет при соединении перезаписывать эту переменную, сохраняя в неё ссылку на свой сокет. Актуальным значением будет в этом случае - последний подсоединившийся клиент.
1
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20
04.12.2020, 12:27  [ТС]
каким образом тогда можно обратиться к ws из вне? Скажем лежит у меня логика ответов в отдельном классе, как достучаться до ws внутри
JavaScript
1
2
3
4
5
 
this.wss = new WebSocket.Server({ server:app }); 
this.wss.on('connection', (ws) => {
   ws.send("") // вот тут
})
0
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
04.12.2020, 13:47
Сохраните ссылку на ws в экземпляре класса, где у вас логика ответов, передав ws в конструктор, а экземпляры классов храните в ассоциативном массиве:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Client {
    constructor(ws) {
        this.ws = ws;
    }
};
 
const clients = {};
 
const httpServer = http.createServer(app);
const wss = new ws.Server({ server: httpServer });
wss.on("connection",
    (ws) =>
    {
        const id = shortId.generate();
        console.log("Client connected. id = " + id);
 
        clients[id] = new Client(ws);
 
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data);
                console.log(msg);
                if (msg.action === "get_id")
                {
                    // ws.send(JSON.stringify({ action: "my_id", id: ws.id }));
                    clients[id].ws.send(JSON.stringify({ action: "my_id", id: id }));
                }
            };
    });
Пример с запросом id, что в одном из прошлых сообщений, но переписанный для ассоциативного массива (клиент остался тем же, без изменений):

app.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const express = require("express");
const http = require("http");
const ws = require("ws");
const path = require("path");
const shortId = require("shortid");
 
const app = express();
app.use(express.static(path.join(__dirname, "./public")));
app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
 
class Client {
    constructor(ws) {
        this.ws = ws;
    }
};
 
const clients = {};
 
const httpServer = http.createServer(app);
const wss = new ws.Server({ server: httpServer });
wss.on("connection",
    (ws) =>
    {
        const id = shortId.generate();
        console.log("Client connected. id = " + id);
 
        clients[id] = new Client(ws);
 
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data);
                console.log(msg);
                if (msg.action === "get_id")
                {
                    // ws.send(JSON.stringify({ action: "my_id", id: ws.id }));
                    clients[id].ws.send(JSON.stringify({ action: "my_id", id: id }));
                }
            };
    });
 
const port = process.env.PORT || 3000;
httpServer.listen(port, () => { console.log("Server started. Port: ", port); });


public/index.html

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Client</title>
</head>
 
<body>
    <button id="btnSend">Click to get my id</button>
    <div id="output" style="font-family: Arial; font-size: 14px;"></div>
 
    <script>
        const btnSend = document.getElementById("btnSend");
        const output = document.getElementById("output");
        output.innerHTML = "Wait for connection...";
        const ws = new WebSocket("ws://localhost:3000");
        ws.onopen =
            () => {
                output.innerHTML = "Connected to the server";
                btnSend.onclick = (event) => {
                    ws.send(JSON.stringify({ action: "get_id" }));
                };
 
                ws.onmessage = (event) => {
                    const msg = JSON.parse(event.data);
                    console.log(msg);
                    if (msg.action === "my_id")
                    {
                        output.innerHTML = `My id: ${msg.id}`;
                    }
                }
            };
    </script>
</body>
 
</html>
1
0 / 0 / 0
Регистрация: 04.06.2016
Сообщений: 20
04.12.2020, 15:46  [ТС]
Вроде понял куда копать. Если в этом была моя ошибка то и в остальном я тоже делаю не правильно... Например у меня есть переменная на сервере player, в нее заносятся данные с бд по слушателю, Потом подключается 2й пользователь, и эта переменная затирается его данными, получается что 1й игрок будет работать с данными 2го игрока....( как это дело можно пофиксить? уже голову сломал(
0
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,966
Записей в блоге: 219
04.12.2020, 16:34
Вы так ничего не сделаете, будете буксовать и терять мотивацию. Лучше разберитесь, как сделано взаимодействие для Крестиков-ноликов в этом примере: https://github.com/formigone/h... ic-tac-toe
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.12.2020, 16:34
Помогаю со студенческими работами здесь

Программа реагирования на ответы пользователя
Добрый день! Помогите, пожалуйста, с решением задачи. Нужно написать программу, которая при ответе от пользователя &quot;Да&quot; на...

Посчитать правильные и неправильные ответы пользователя
Товарищи форумчане! Прошу вашей помощи, нужно посчитать правильные и неправильные ответы пользователя. Помогите разобраться ))))def P3(): ...

Как принимать ответы пользователя в программе тестирования
Парни, мне нужно сделать приложение типа, вопрос - ответ. как сделать, чтобы текст, который один раз вписал, не проходил сразу все...

Разработать программу, которая считывает и выводит на экран вопро с из файла, получает ответы пользователя
В текстовом файле хранятся 5 вопросов, на которые можно отвечать «да» или «нет», после каждого вопроса на следующей строке хранится...

WebSocket для python 3
Какой посоветуете выбрать framework для реализации websocket'ов на python 3? Просто попробовал уже 2 из них: websocket-server и ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru