Websocket-springboot-starter для разработки websocket.
Проект в основном подходит для серверных сценариев, где данные изменяются и требуется активно уведомлять клиента, например, веб-чаты, уведомления об изменениях данных на веб-странице и т. д. Он решает проблему двусторонней связи между сервером и клиентом и может заменить технологию опроса ajax. В сценарии активного уведомления сервера он может значительно снизить сложность архитектуры.
При разработке WebSocket обычно возникают две проблемы:
Обычно мы используем Map
для хранения Session
, вы увидите что-то вроде этого в классе @ServerEndPoint
:
public static final Map<String , Session> sessions = new ConcurrentHashMap<>();
Но это может быть не очень удобно расширять. Исходя из этого, этот проект рассматривает обработку кода Session
как интерфейс WebSocketManager
, который реализует одноузловую и кластерную версии, так что использование в двух сценариях полностью одинаково.
public interface WebSocketManager {
/**
* Имя в контейнере
*/
String WEBSOCKET_MANAGER_NAME = "webSocketManager";
/**
* Получить websocket session по идентификатору
* @param identifier Идентификатор
* @return WebSocket
*/
WebSocket get(String identifier);
/**
* Поместить websocket session
* @param identifier Идентификатор
* @param webSocket websocket
*/
void put(String identifier, WebSocket webSocket);
/**
* Удалить
* @param identifier Идентификатор
*/
void remove(String identifier);
/**
* Получить все сохраненные WebSocket на текущем компьютере
* @return Карта WebSocket
*/
Map<String , WebSocket> localWebSocketMap();
/**
* Подсчитать общее количество онлайн-пользователей
* @return Общее количество онлайн-пользователей
*/
default int size(){
return localWebSocketMap().size();
}
/**
* Отправить сообщение определенному человеку
* @param identifier Идентификатор
* @param message Сообщение
*/
void sendMessage(String identifier, String message);
/**
* Широковещательное сообщение
* @param message Сообщение
*/
void broadcast(String message);
/**
* Вызов функции при получении сообщения от WebSocket
* @param identifier Идентификатор
* @param message Содержание сообщения
*/
void onMessage(String identifier , String message);
/**
* Определить, является ли сообщение в OnMessage сообщением ping в сообщении от клиента
* @param identifier Идентификатор
* @param message Сообщение
* @return Является ли это сообщением ping
*/
default boolean isPing(String identifier , String message){
return "ping".equalsIgnoreCase(message);
}
/**
* Вернуть сообщение pong
* @param identifier Идентификатор
* @param message Сообщение
* @return Сообщение pong
*/
default String pong(String identifier , String message){
return "pong";
}
}
Кластерная версия основана на функции публикации и подписки Redis, почему она такая сложная? Нельзя ли просто сохранить его в Redis, как HttpSession? Нет, потому что WebSocket Session
нельзя сериализовать. java.io.NotSerializableException
.
Используйте интерфейс WebSocketManager
при использовании, поддерживающий одноузловые (на основе памяти) и кластерные (на основе публикации и подписки Redis) версии.
JFinal или другие веб-архитектуры для разработки WebSocket см. https://gitee.com/xxssyyyyssxx/jfinal-websocket.
compile 'top.jfunc.websocket:websocket-springboot-starter:1.8.2.4'
maven { url 'https://jitpack.io' }
compile 'com.gitee.xxssyyyyssxx:websocket-springboot-starter:1.8.4'
Использование см. https://gitee.com/xxssyyyyssxx/websocket-demo.
/**
* 1. Расширить top.jfunc.websocket.BaseWebSocketEndpoint
* 2. Отметить @Component @ServerEndpoint
* @author xiongshiyan
*/
@Component
@ServerEndpoint(value ="/websocket/connect/{identifier}")
public class WebSocketEndpoint extends top.jfunc.websocket.BaseWebSocketEndpoint{
}
@EnableMemWebSocketManager для одноузлового управления
или
@EnableRedisWebSocketManager использовать механизм кластера Redis для реализации кластеризации
@Configuration
public class WebSocketConfig {
/**
* См. https://www.cnblogs.com/betterboyz/p/8669879.html
* Сначала необходимо внедрить ServerEndpointExporter, этот bean автоматически зарегистрирует Websocket endpoint, объявленный с помощью аннотации @ServerEndpoint.
* Обратите внимание, что если вы используете независимый контейнер сервлетов, а не встроенный контейнер springboot напрямую, не вводите ServerEndpointExporter,
* потому что он будет предоставлен и управляется контейнером, иначе будет сообщено о повторяющейся ошибке endpoint.
*/
@ConditionalOnProperty(prefix = "server.websocket.exporter" ,
name = "enable" ,havingValue = "true")
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
/**
* Можно использовать свой собственный WebSocketManager, обратите внимание на фиксированное имя
*/
/*@Bean(WebSocketManager.WEBSOCKET_MANAGER_NAME)
public WebSocketManager webSocketManager(){
``` Если используется **Nginx** в качестве балансировщика нагрузки, то необходимо добавить в конфигурацию:
Nginx обратный прокси должен поддерживать WebSocket, для этого нужно настроить несколько заголовков, иначе при подключении будет ошибка 404. proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; //при небольшом времени легко разорвать соединение
Что касается мониторинга сердцебиения, можно настроить его самостоятельно, имитируя `top.jfunc.websocket.config.WebSocketSchedulingConfig`. Добавьте три параметра конфигурации для включения мониторинга сердцебиения:
- webSocket.heartCheck.enabled=true
- webSocket.heartCheck.timeSpan=1000
- webSocket.heartCheck.errorToleration=30
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )