Как разделить соединение WebSocket между различными html страницами? - PullRequest
0 голосов
/ 05 февраля 2020

Я хочу использовать WebSockets для базового c Java Spring Web проекта. Я новичок в этом топи c и уже некоторое время исследую его. Вот демонстрация, которую я успешно выполнил: http://zetcode.com/spring/websocket/

Я хочу добиться того, чтобы события, выполненные на разных страницах HTML, вызывали изменения, относящиеся к определенной другой. Нужно ли создавать экземпляр WebSocket на всех страницах и отправлять данные для данного события и иметь функциональность .onmessage на одной странице, где будут происходить обновления HTML (с помощью JavaScript)? Или мне нужно поделиться WebSocket с JS sessionStorage?

Вот зависимости, которые я использую до сих пор:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>

1 Ответ

0 голосов
/ 16 февраля 2020

Чтобы разделить одно WebSocket соединение между различными html страницами, вам нужно использовать SharedWorker.
Я исследовал похожую топику c и случайно сделал простой пример, поэтому я хотел бы кратко объясните это и покажите простой пример исходного кода.


Решения того, чего вы хотите достичь

Из вашего вопроса

То, чего я хочу добиться, - это чтобы события, выполненные на разных HTML страницах, вызывали изменения для конкретной другой.

  1. WebSocket на всех страницах
  2. SharedWorker

Это может быть достигнуто путем создания WebSocket соединения на всех страницах (решение 1).
Когда вы хотите уменьшить количество WebSocket Для каждого клиента (для уменьшения нагрузки на сервер) SharedWorker будет лучшим выбором (решение 2).
Я думаю, что вы уже поняли решение 1 и ищете лучшее решение, поэтому вы спрашиваете :

Как открыть соединение через WebSocket между различными html страницами?

Так что я хотел бы написать в основном о SharedWorker здесь.

[ПРИМЕЧАНИЕ] Вы не можете поделиться WebSocket соединением, используя sessionStorage и localStorage, потому что они не хранят javascript сам объект, но обрабатывают пары ключ / значение строки ( Хранение Объекты в HTML5 localStorage ).


О совместном работнике

От SharedWorker - MDN ,

спецификация c вид работника, к которому можно получить доступ из нескольких контекстов просмотра, таких как несколько windows, iframes или даже работники.

Работник (Web Worker) работает в javascript фон. Вы можете использовать WebSocket в работнике.
Когда вы создаете соединение в SharedWorker, вы можете использовать одно и то же (общее) соединение на нескольких страницах html через работника.


Shared Worker Простой пример

У нас есть 2 разные html страницы:

  • http://localhost:8080/pageA.html
  • http://localhost:8080/pageB.html

У них есть кнопка с именем message. Когда кнопка нажата:

  1. Они отправляют сообщение на SharedWorker, и рабочий отправляет сообщение на сервер, используя общее WebSocket соединение.
  2. Сервер отвечает на сообщение клиента и отправьте сообщение работнику.
  3. 2 html страницы получают сообщение сервера от работника.

[сторона сервера - WebSocketHandler используя Spring]

/**
 * End point '/hellows' 
 */
public class MyWebsocketHnadler extends TextWebSocketHandler {

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("Message from client : " + message.getPayload());
        session.sendMessage(new TextMessage("Server responds to '" + message.getPayload() + "'"));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("Connection is opened.");
        session.sendMessage(new TextMessage("Open"));
    }
}

[сторона клиента - pageA. html & pageB.html]

<!-- For simplicity I omit DOCTYPE, html tag, head tag and body tag here -->
<button type="button" id="msg-btn"/>message</button>
<script src="main.js"></script>

[сторона клиента - main.js]

const worker = new SharedWorker("worker.js");
worker.port.start();
// post message in order to make worker to push this page's port to port array.
worker.port.postMessage({ id: location.href });
worker.port.addEventListener("message", e => console.log(e.data.msg));

document.querySelector("#msg-btn").addEventListener("click", () => {
  worker.port.postMessage({ msg: "I am " + location.href });
});

[сторона клиента - worker.js]

const ports = {};
const ws = new WebSocket("ws://localhost:8080/hellows");

ws.addEventListener("message", e => {
  Object.values(ports).forEach(port => {
    port.postMessage({ msg: "From sever: " + e.data });
  });
});

addEventListener("connect", e => {
  const port = e.ports[0];
  port.start();
  port.addEventListener("message", e => {
    // if you open same html page at multiple windows,
    // only newest window can send and recieve a message.
    if (e.data.id) ports[e.data.id] = port;
    if (e.data.msg) ws.send(e.data.msg);
  });
});

Когда мы обращаемся к pageA и pageB, а затем нажимаем message кнопки одну за другой, мы получаем такой результат:

[server боковая консоль]

Connection is opened.
Message from client : I am http://localhost:8080/pageA.html
Message from client : I am http://localhost:8080/pageB.html
Message from client : I am http://localhost:8080/pageA.html

[клиентская сторона - pageA. html консоль]

From sever: Open
From sever: Server responds to 'I am http://localhost:8080/pageA.html'
From sever: Server responds to 'I am http://localhost:8080/pageB.html'
From sever: Server responds to 'I am http://localhost:8080/pageA.html'

[клиентская сторона - pageB. html консоль]

From sever: Server responds to 'I am http://localhost:8080/pageA.html'
From sever: Server responds to 'I am http://localhost:8080/pageB.html'
From sever: Server responds to 'I am http://localhost:8080/pageA.html'




Рассмотрение

  1. Какие браузеры вы должны поддерживать?

Некоторые браузеры не поддерживают Sha красный Рабочий ( Могу ли я использовать ... ).


См. Также :

API Web Workers - MDN
SharedWorker - MDN
Масштабирование подключений WebSocket с использованием общих работников - Аю sh Гупта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...