Обзор
Серию рассказов о WebSocket планируется разделить на пять глав и шесть глав, чтобы представить WebSocket и узнать, как быстро создавать и использовать возможности, предоставляемые WebSocket в Springboot. В эту серию планов входят следующие статьи:
Часть 1, что такое WebSocket и для чего он используется
Вторая статья, как использовать STOMP для быстрой сборки режима широковещательных сообщений WebSocket в Spring
Третья статья в Springboot о том, как использовать WebSocket и STOMP для быстрого создания режима двухточечных сообщений (1)
Четвертая часть, в Springboot, как использовать WebSocket и STOMP для быстрого создания режима сообщений точка-точка (2)
Пятая статья в Springboot реализует собственный агент сообщений WebSocket для веб-чатов.
Шестая статья в Springboot реализует более гибкий WebSocket.
Основная линия этой статьи
Это последняя статья в этой серии, и в ней будет представлен еще один способ реализации WebSocket. Простой чат по-прежнему будет использоваться в качестве примера. До сих пор мы также можем выбирать различные методы реализации в зависимости от конкретной ситуации.
Соответствующие читатели этой статьи
Целеустремленные молодые люди, которые хотят знать, как настраивать и реализовывать более сложную логику продукта WebSocket в Springboot.
Используйте поддержку WebSocket, предоставляемую Tomcat
ужеJava EE 7
, он был опубликованJSR356
Спецификация. Начиная с Tomcat7.0.47, он также поддерживает унифицированныеWebSocket
интерфейс. в настоящее время используетSpringboot
также можно легко использоватьTomcat
предоставляемые этими API. Сегодня мы испытаемTomcat
осуществленныйWebSocket
.
1. Введите зависимости
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
Springboot имеет встроенный tomcat, мы можем напрямую представить этот расширенный компонент Spring. Кстати, расширенные компоненты Springboot будут автоматически ссылаться на базовые компоненты, такие какspring-boot-starter-websocket
представилspring-boot-starter-web
иspring-boot-starter
, поэтому не вводите его повторно.
2. Создайте конечную точку WebSocket, используя @ServerEndpoint
ввести сначалаServerEndpointExporter
, этот bean-компонент будет автоматически зарегистрирован и использован@ServerEndpoint
Конечная точка WebSocket, объявленная аннотацией.
package com.draw.wsdraw.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
Затем мы начинаем реализовывать класс реализации службы WebSocket, вотWebSocketServer
, не забудьте использовать@ServerEndpint
и@Component
под заявлением. Несмотря на то что@Component
По умолчанию используется одноэлементный режим, но Springboot по-прежнему будет инициализировать его для каждого соединения WebSocket.Bean
, поэтому его можно сохранить со статической картой. Другими словами, каждый раз, когда пользователь устанавливает соединение с сервером,WebSocketServer
объект, нажмите этот объектroomId
Сохранить какHashMap
, что удобно для последующего использования.
При создании ServerEndpoint нужно соответствовать нескольким функциональным методам, необходимым для его реализации:OnOpen、OnMessage、OnClose、OnError
.
-
@OnOpen
: когда клиент инициирует установление соединения с сервером, сервер вызывает, и параметры, которые могут быть переданы, — это Session (сеанс WebSocket) и EndpointConfig. Кроме того, можно добавить параметры, аннотированные с помощью @PathParam. Параметр, который мы аннотировали здесь, — это roomId, то есть параметр адреса запроса, передаваемый при установлении соединения, который имеет ту же функцию, что и {INFO}, представленный в нашей предыдущей статье. -
@OnMessage
: Вызывается при поступлении сообщения клиента, включая сеанс, в соответствии с формой сообщения, если это текстовое сообщение, передать параметр типа String или Reader, если это двоичное сообщение, передать тип byte[] параметр или InputStream. -
@OnClose
: вызывается при разрыве соединения и закрытии WebSocket. -
@OnError
: вызывается при возникновении ошибки, передавая сеанс исключения и сообщение об ошибке.
Переписав описанный выше метод, можно реализовать бизнес-логику WebSocket на стороне сервера.
@ServerEndpoint("/webSocket/{roomId}")
@Component
public class WebSocketServer {
private static ConcurrentHashMap<String, List<WebSocketServer>> webSocketMap =
new ConcurrentHashMap<>(3);
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//接收roomId
private String roomId = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, EndpointConfig config, @PathParam("roomId") String roomId) {
if (roomId == null || roomId.isEmpty()) return;
this.session = session;
this.roomId = roomId;
addSocketServer2Map(this);
try {
sendMessage("连接成功", true);
} catch (IOException e) {
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
List<WebSocketServer> wssList = webSocketMap.get(roomId);
if (wssList != null) {
for (WebSocketServer item : wssList) {
if (item.session.getId().equals(session.getId())) {
wssList.remove(item);
if (wssList.isEmpty()) {
webSocketMap.remove(roomId);
}
break;
}
}
}
}
/**
* 收到客户端消息后调用的方法
*/
@OnMessage
public void onMessage(String message, Session session) {
//群发消息
String msg = filterMessage(message);
if (msg != null) {
sendInfo(msg, roomId, session);
}
}
/**
* 发生错误时,调用的方法
*/
@OnError
public void onError(Session session, Throwable error) {
}
Таким образом, код на стороне сервера завершен, здесь размещена только часть исходного кода, а адрес исходного кода проекта будет указан далее в статье.
3. Реализовать клиентскую страницу
<script type="text/javascript">
var ws;
function setConnected(connected){
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
$("#response").html();
}
function connect(){
var roomId = $('#roomId').val();
ws = new WebSocket('ws://localhost:8080/webSocket/' + roomId);
ws.onopen = WSonOpen;
ws.onmessage = WSonMessage;
ws.onclose = WSonClose;
ws.onerror = WSonError;
}
function WSonOpen() {
var message = {
name:'Server',
chatContent:'成功连接'
}
setConnected(true);
showResponse(message)
};
function WSonMessage(event) {
var message = {
name:'Server',
chatContent:event.data
}
showResponse(message)
};
function WSonClose() {
var message = {
name:'Server',
chatContent:'已断开'
}
showResponse(message)
};
function WSonError() {
var message = {
name:'Server',
chatContent:'连接错误!'
}
showResponse(message)
};
function disconnect(){
ws.close()
setConnected(false);
console.log("Disconnected");
}
function sendMessage(){
var chatContent = $("#chatContent").val();
var roomId = $('#roomId').val();
ws.send(JSON.stringify({'roomId':roomId,'chatContent':chatContent}))
}
function showResponse(message){
var response = $("#response").val();
$("#response").val(response+message.name+': '+message.chatContent+'\n');
}
</script>
Страница клиента реализует простые функции подключения, отключения и отправки сообщений. Эта часть подробно не описана.
4. Скриншот демо
Адрес источника
Адрес источника этой статьи:
Другой способ реализации WebSocket
Суммировать
В этой статье напрямую используется WebSocket, предоставленный Tomcat, который также является относительно гибкой реализацией.Его нужно реализовать только в соответствии с описанными выше шагами. Сосредоточьтесь на написании кода бизнес-логики.
Во всей серии мы представили несколько способов реализации WebSocket, некоторые из которых являются высокоинтегрированными, а некоторые относительно гибкими. Вы можете выбрать подходящий метод в соответствии с фактическими потребностями бизнеса. На этом серия закончилась. Спасибо всем за чтение.
Произведено Сяомином, это должен быть бутик
Добро пожаловать на технический форум xNPE, ежедневно появляется все больше оригинальных галантерейных товаров.