Недавно я получил бизнес-требование, и мне нужно было создать интерфейс для отображения информации чата в режиме реального времени, что требует установления соединения через веб-сокет с сервером для получения данных в реальном времени и обновления представлений в реальном времени. Реализация здесь, я надеюсь, что смогу помочь тем, у кого такие же потребности. Без лишних слов позвольте мне рассказать о моем процессе реализации:
помещение
Чтобы протестировать код в статье, вам нужно, чтобы разработчик на стороне сервера сотрудничал с вами и предоставлял соответствующие интерфейсы связи для завершения связи между клиентом и сервером.Для обеспечения связи нам нужно использовать другой модульsockjs-clientмодули иstomjsМодули, далее я дам краткое введение в эти два модуля.
Позже я напишу статью об использовании NodeJS+SockJS для реализации функции видеоэкрана, так что следите за обновлениями~
Об общении в реальном времени
Для достижения связи в реальном времени у нас обычно есть три метода:
- ajax-опрос
Принцип ajax-опроса очень прост, пусть браузер каждые несколько секунд отправляет запрос, подобный серверу, спрашивая сервер, есть ли новая информация.
- http длинный опрос
Механизм длительного опроса аналогичен механизму ajax-опроса, и оба используют метод опроса, но в прошлом это была модель блокировки (вызов все время и не вешать трубку, если не получено), то есть, после того, как клиент инициирует ссылку, если нет сообщения, он не вернул ответ клиенту.Он будет возвращаться только до тех пор, пока не появится новое сообщение.После возврата клиент снова установит соединение, и цикл начнется опять и опять.
- WebSocket
WebSocket – это протокол, предоставляемый HTML5 для полнодуплексной связи по одному TCP-соединению. В WebSocket API браузеру и серверу нужно только выполнить рукопожатие, а затем между браузером и сервером устанавливается соединение. Expressway. Данные могут напрямую передаваться друг другу между ними, и нет необходимости в утомительных запросах и ожиданиях. Из приведенного выше введения легко увидеть, что как опрос ajax, так и длинный опрос очень ресурсоемки.Ajax-опрос требует, чтобы сервер имел высокую скорость обработки и ресурсы, а длинный опрос http требует высокого параллелизма, то есть возможность получать клиентов одновременно.С WebSocket требуется только один HTTP-запрос для отправки и получения сообщений на сервер и с сервера.
sockjs-client
sockjs-clientЭто коммуникационный модуль, отделенный от SockJS для использования на стороне клиента, поэтому давайте посмотрим на SockJS напрямую. SockJS — это библиотека JavaScript для браузера, которая предоставляет веб-объект. SockJS предоставляет согласованный кросс-браузерный API-интерфейс JavaScript, который создает полнодуплексный междоменный канал связи с малой задержкой между браузером и веб-сервером. Вы можете спросить, почему я должен использовать SockJS, а не просто использовать нативный WebSocket?Это связано с большой особенностью SockJS, некоторые браузеры не поддерживают WebSocket, поэтому необходим резервный вариант, а Spring Framework предоставляет прозрачный резервный вариант на основе на протоколе SockJS. SockJS обеспечивает совместимость с браузером и предпочитает собственный WebSocket.Если браузер не поддерживает WebSocket, SockJS автоматически переключится на опрос.
stomjs
STOMP (Simple Text-Oriented Messaging Protocol) простой текстовый протокол, ориентированный на сообщения; WebSocket — это архитектура обмена сообщениями, которая не требует использования какого-либо конкретного протокола обмена сообщениями, она полагается на прикладной уровень для интерпретации значения сообщений. В отличие от HTTP, WebSocket представляет собой очень тонкий слой на TCP, который преобразует потоки байтов в текстовые/двоичные сообщения.Поэтому для практических приложений уровень связи WebSocket слишком низок.Поэтому его можно использовать между WebSockets.Протокол STOMP использован выше, чтобы добавить соответствующую семантику сообщений для связи между браузером и сервером.
Связь между STOMP и WebSocket:
- Протокол HTTP решает детали веб-браузера, инициирующего запрос, и веб-сервера, отвечающего на запрос.Предполагая, что протокол HTTP не существует, вы можете использовать сокеты TCP только для написания веб-приложений.Вы можете подумать, что это безумие ;
- Использование WebSocket (SockJS) напрямую очень похоже на использование сокетов TCP для написания веб-приложений, потому что здесь нет высокоуровневого протокола, нам нужно определить семантику отправки сообщений между приложениями, и нам нужно убедиться, что оба конца соединения может следовать этой семантике;
- Точно так же, как HTTP добавляет уровень модели «запрос-ответ» поверх сокетов TCP, STOMP предоставляет уровень формата проводки на основе фреймов поверх WebSocket для определения семантики сообщений.
Код
В дополнение к самому основному соединению в коде также установлен таймер, который отправляет порцию данных на сервер каждые десять секунд.Если возникает ошибка, перехватывайте ошибку и переустанавливайте соединение.
// 安装并引入相关模块
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
export default {
data() {
return {
dataList: []
};
},
mounted:function(){
this.initWebSocket();
},
beforeDestroy: function () {
// 页面离开时断开连接,清除定时器
this.disconnect();
clearInterval(this.timer);
},
methods: {
initWebSocket() {
this.connection();
let self = this;
// 断开重连机制,尝试发送消息,捕获异常发生时重连
this.timer = setInterval(() => {
try {
self.stompClient.send("test");
} catch (err) {
console.log("断线了: " + err);
self.connection();
}
}, 5000);
},
removeTab(targetName) {
console.log(targetName)
},
connection() {
// 建立连接对象
this.socket = new SockJS('http://xxxxxx:8089/ws');//连接服务端提供的通信接口,连接以后才可以订阅广播消息和个人消息
// 获取STOMP子协议的客户端对象
this.stompClient = Stomp.over(this.socket);
// 定义客户端的认证信息,按需求配置
var headers = {
login: 'mylogin',
passcode: 'mypasscode',
// additional header
'client-id': 'my-client-id'
};
// 向服务器发起websocket连接
this.stompClient.connect(headers,(frame) => {
this.stompClient.subscribe('/topic/chat_msg', (msg) => { // 订阅服务端提供的某个topic
consolel.log(msg.body); // msg.body存放的是服务端发送给我们的信息
});
}, (err) => {
// 连接发生错误时的处理函数
console.log(err);
});
},
// 断开连接
disconnect() {
if (this.stompClient != null) {
this.stompClient.disconnect();
console.log("Disconnected");
}
}
}
};
Эпилог
Я не знаю, ясно ли я написал. У меня мало знаний и ограниченные навыки выражения. Если есть что-то, чего вы не понимаете, вы можете отправить свои вопросы на мою электронную почту.2510909248@qq.com, Кроме того, если у вас есть какие-либо хорошие комментарии или предложения, вы также можете беспокоить~~~
Ссылка на ссылку
websocket: поддержка внешнего подключения + подписка
Прошлые статьи
Expires, Last-Modified, механизм кэширования Etag
Научите, как сделать приостановку заголовка таблицы (фиксированный заголовок таблицы)