- Vue
- wsUrl:
- Sec-WebSocket-Protocol:
- webSocket = new WebSocket(wsUrl, Sec-WebSocket-Protocol)
- webSocket.onopen = function(){}
- webSocket.onmessage = function(){}
- webSocket.onclose = function(){}
- webSocket.onerror = function(){}
- heartCheck
- Nginx
http { upstream branchBackup { server 117.51.156.xxx:18081; server 117.51.156.xxx:28081 backup; } #后端平台管理系统接口 location ^~ /branch/api-v1/ws/ { proxy_pass http://branchBackup; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } } - ApplicationContext发布通知事件
- 发布事件
applicationContext.publishEvent(new ServiceNonstandardCheckEvent(this, id, checkStatus, serviceNonstandardEntity.getOperatorId())); - 定义事件实体类(继承ApplicationEvent)
package com.das.listener.event.notification; import lombok.Getter; import lombok.Setter; import org.springframework.context.ApplicationEvent; /** * @Author liangmy * @Description: * @Create: 2021/1/19 上午11:26 */ @Getter @Setter public class ServiceNonstandardCheckEvent extends ApplicationEvent { /** * 询价服务唯一标志 */ private Long serviceNonstandardId; /** * 询价服务审核操作 * true :审核通过 * false : 审核拒绝 */ private Boolean checkStatus; /** * 通知接收账号唯一标志 */ private Long systemUserId; /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public ServiceNonstandardCheckEvent(Object source) { super(source); } public ServiceNonstandardCheckEvent(Object source, Long serviceNonstandardId, Boolean checkStatus, Long systemUserId) { super(source); this.serviceNonstandardId = serviceNonstandardId; this.checkStatus = checkStatus; this.systemUserId = systemUserId; } } - 定义事件监听者(实现ApplicationListener<ApplicationEvent>)
package com.das.listener.notification; import com.alibaba.fastjson.JSON; import com.das.common.constant.EtcConstant; import com.das.common.constant.RedisPrefixConstant; import com.das.entity.system.NotificationEntity; import com.das.listener.event.notification.ServiceNonstandardCheckEvent; import com.das.service.notification.NotificationServiceManager; import com.das.service.redis.RedisService; import com.das.thirdParty.tim.TimService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * @Author liangmy * @Description: * @Create: 2021/1/19 上午11:33 */ @Slf4j @Component public class ServiceNonstandardCheckListener implements ApplicationListener<ServiceNonstandardCheckEvent> { @Autowired private NotificationServiceManager notificationServiceManager; @Autowired private RedisService redisService; @Autowired private TimService timService; @Override public void onApplicationEvent(ServiceNonstandardCheckEvent event) { // 1. 持久化通知信息 log.info("saveNotificationAndReceiverForServiceNonstandarCheck(Long serviceNonstandardId, Boolean checkStatus, Long systemUserId) : {}, {}, {}", event.getServiceNonstandardId(), event.getCheckStatus(), event.getSystemUserId()); Long notificationId = notificationServiceManager.saveNotificationAndReceiverForServiceNonstandarCheck(event.getServiceNonstandardId(), event.getCheckStatus(), event.getSystemUserId()); if (EtcConstant.assertLegalParam(notificationId)) { // 2. 发布消息到 serviceNonstandarCheck 频道 NotificationEntity notificationEntity = new NotificationEntity(); notificationEntity.setId(notificationId); log.info("convertAndSend(RedisPrefixConstant.SubcribeTopic.serviceNonstandarCheck : {}", JSON.toJSONString(notificationEntity)); redisService.convertAndSend(RedisPrefixConstant.SubcribeTopic.serviceNonstandarCheck, notificationEntity); // 3. 发布消息到 IM log.info("sendmsgForServiceNonstandardCheck(Long systemUserId, Long serviceNonstandardId, Boolean checkStatus) : {}, {}, {}", event.getSystemUserId(), event.getServiceNonstandardId(), event.getCheckStatus()); timService.sendmsgForServiceNonstandardCheck(event.getSystemUserId(), event.getServiceNonstandardId(), event.getCheckStatus()); } } }- 持久化通知信息
- 定义通知信息Subjoin类
package com.das.entity.system.notification; import lombok.Getter; import lombok.Setter; /** * @Author liangmy * @Description: * @Create: 2021/1/19 下午2:04 */ @Getter @Setter public class NotificationSubjoinServiceNonstandardCheckEntity { /** * 询价服务唯一标志 */ private Long serviceNonstandardId; /** * 询价服务审核状态 * true : 审核通过 * false : 审核拒绝 */ private Boolean checkStatus; /** * 询价服务创建人账号标志 */ private Long operatorId; } - 持久化通知信息逻辑
/** * 持久化通知及通知接收人,并返回通知id(询价服务审核通过/审核拒绝) * * @param serviceNonstandardId * @param checkStatus * @param systemUserId 接收通知账号唯一标志 * @return */ @Override public Long saveNotificationAndReceiverForServiceNonstandarCheck(Long serviceNonstandardId, Boolean checkStatus, Long systemUserId) { if (!EtcConstant.assertLegalParam(serviceNonstandardId) || null == checkStatus) { throw DasException.internalError(null, messageSource.getMessage(EtcConstant.MessageCode.param_missing, null, LocaleContextHolder.getLocale())); } NotificationEntity notificationEntity = new NotificationEntity(); notificationEntity.setType(NotificationTypeEnum.SERVICE_NONSTANDAR_CHECK); notificationEntity.setContent(EtcConstant.WsMessage.NotificationConstant.content_service_nonstandar_check); NotificationSubjoinServiceNonstandardCheckEntity notificationSubjoinServiceNonstandardCheckEntity = new NotificationSubjoinServiceNonstandardCheckEntity(); notificationSubjoinServiceNonstandardCheckEntity.setServiceNonstandardId(serviceNonstandardId); notificationSubjoinServiceNonstandardCheckEntity.setCheckStatus(checkStatus); notificationEntity.setSubjoin(JSON.toJSONString(notificationSubjoinServiceNonstandardCheckEntity)); notificationMapper.save(notificationEntity); List<NotificationReceiverEntity> notificationReceiverEntityList = new LinkedList<>(); NotificationReceiverEntity notificationReceiverEntity = new NotificationReceiverEntity(); notificationReceiverEntity.setNotificationId(notificationEntity.getId()); SystemUserEntity systemUserEntity = systemUserService.getSysUser(systemUserId); if (null == systemUserEntity) { throw DasException.notAllowed(null, messageSource.getMessage(EtcConstant.MessageCode.system_user_not_exist, null, LocaleContextHolder.getLocale())); } String receiverKey = EtcConstant.getKey(systemUserId, systemUserEntity.getStoreBaseId()); notificationReceiverEntity.setReceiverKey(receiverKey); notificationReceiverEntityList.add(notificationReceiverEntity); notificationReceiverMappper.saveBatch(notificationReceiverEntityList); return notificationEntity.getId(); }
- 定义通知信息Subjoin类
- 发布消息到指定频道
- 定义Redis 发布订阅频道
/** * Redis 发布订阅频道 */ public static class SubcribeTopic { public static final String completeWork = "channel:ws:completeWork"; public static final String serviceNonstandarCheck = "channel:ws:serviceNonstandarCheck"; public static final String appointmentService = "channel:ws:appointmentService"; public static final String carPlanRemind = "channel:ws:carPlanRemind"; } - 发布消息到 serviceNonstandarCheck 频道
NotificationEntity notificationEntity = new NotificationEntity(); notificationEntity.setId(notificationId); redisService.convertAndSend(RedisPrefixConstant.SubcribeTopic.serviceNonstandarCheck, notificationEntity);
- 定义Redis 发布订阅频道
- 持久化通知信息
- 发布事件
-
Redis 发布订阅模式
- 定义观察者RedisReceiver(实现org.springframework.data.redis.connection.MessageListener)
package com.das.listener.redis; import com.alibaba.fastjson.JSON; import com.das.common.constant.EtcConstant; import com.das.common.constant.RedisPrefixConstant; import com.das.entity.system.NotificationEntity; import com.das.mapper.system.NotificationMapper; import com.das.service.ws.WsMessageService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; /** * @Author liangmy * @Description: * @Create: 2020/11/4 下午7:35 */ @Slf4j @Component public class RedisReceiver implements MessageListener { @Autowired private ApplicationContext applicationContext; @Autowired private NotificationMapper notificationMapper; @Autowired private WsMessageService wsMessageService; @Override public void onMessage(Message message, byte[] bytes) { String channel = new String(message.getChannel()); String body = new String(message.getBody()); log.info("message.getChannel():{}", channel); log.info("message.getBody():{}", body); log.info("term:{}", EtcConstant.notificationTerm); body = body.substring(1, body.length() - 1); log.info("message.getBody():{}", body); NotificationEntity notificationEntity = JSON.parseObject(body, NotificationEntity.class); log.info("message.getBody()::parseObject:{}", JSON.toJSONString(notificationEntity)); log.info("notificationEntity.getId() : {}", notificationEntity.getId()); List<NotificationEntity> notificationEntityPushList = notificationMapper.getNotificationEntityPushList(notificationEntity.getId()); for (int i = 0; CollectionUtils.isEmpty(notificationEntityPushList) && i < 5; i++) { log.info("notificationMapper.getNotificationEntityPushList(notificationEntity.getId()) is empty, try again. times : {}. notificationEntity.getId() : {}", i, notificationEntity.getId()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { log.info("notificationMapper.getNotificationEntityPushList(notificationEntity.getId()) sleep Interrupted. notificationEntity.getId() : {}", notificationEntity.getId()); } notificationEntityPushList = notificationMapper.getNotificationEntityPushList(notificationEntity.getId()); } List<String> alarmCountMessageOperatorKeyList = new LinkedList<>(); switch (channel) { case RedisPrefixConstant.SubcribeTopic.completeWork: case RedisPrefixConstant.SubcribeTopic.appointmentService: case RedisPrefixConstant.SubcribeTopic.carPlanRemind: case RedisPrefixConstant.SubcribeTopic.serviceNonstandarCheck: log.info("推送通知:{}", JSON.toJSONString(notificationEntityPushList)); wsMessageService.pushNotificationList(notificationEntityPushList); for (NotificationEntity notificationEntityAlarmCount : notificationEntityPushList) { alarmCountMessageOperatorKeyList.add(notificationEntityAlarmCount.getReceiverKey()); } wsMessageService.pushAlarmCountMessageList(alarmCountMessageOperatorKeyList); log.info("推送通知数量:{}", JSON.toJSONString(alarmCountMessageOperatorKeyList)); break; default: break; } } }- 推送通知
@Override public void pushNotificationList(List<NotificationEntity> notificationEntityPushList) { WsMessageEntity wsMessageEntity = null; for (NotificationEntity notificationEntity : notificationEntityPushList) { String receiverKey = notificationEntity.getReceiverKey(); log.info("推送通知。获取接受人:{}", receiverKey); if (StringUtils.isBlank(receiverKey)) { continue; } log.info("推送通知。获取通知类型:{}", notificationEntity.getType()); notificationEntity.setTypeDesc(littleBear.getEnumValue(notificationEntity.getType())); log.info("parse Notification::subjoin : {}", notificationEntity.getSubjoin()); switch (notificationEntity.getType()) { case SERVICE_NONSTANDAR_CHECK: String downloadUrl = ""; NotificationSubjoinServiceNonstandardCheckEntity notificationSubjoinServiceNonstandardCheckEntity = JSON.parseObject(notificationEntity.getSubjoin(), NotificationSubjoinServiceNonstandardCheckEntity.class); if (null != notificationSubjoinServiceNonstandardCheckEntity) { SystemUserEntity systemUserEntity = systemUserMapper.getById(notificationSubjoinServiceNonstandardCheckEntity.getOperatorId()); if (null != systemUserEntity) { downloadUrl = ossService.getDownloadUrl(systemUserEntity.getPortraitResourceId()); notificationSubjoinServiceNonstandardCheckEntity.setOperatorImgUrl(downloadUrl); } } notificationEntity.setOperatorImgUrl(downloadUrl); notificationEntity.setSubjoin(JSON.toJSONString(notificationSubjoinServiceNonstandardCheckEntity)); notificationEntity.setSubjoinEntity(notificationSubjoinServiceNonstandardCheckEntity); break; default: break; } WsMessageTermEnum term = WsMessageTermEnum.valueOf(EtcConstant.notificationTerm); String receiverKeyTerm = EtcConstant.getKey(receiverKey, term); wsMessageEntity = new WsMessageEntity(WsMessageTypeEnum.notify, receiverKeyTerm); wsMessageEntity.setBodyClazz(notificationEntity.getClass().getName()); wsMessageEntity.setBody(notificationEntity); AbstractWebSocketServer.sendMsg(receiverKeyTerm, wsMessageEntity); log.info("通知推送。用户:{}, 通知:{}", receiverKeyTerm, JSON.toJSONString(wsMessageEntity)); } } - 推送通知数量
@Override public void pushAlarmCountMessageList(List<String> alarmCountMessageOperatorKeyList) { for (String receiverKey : alarmCountMessageOperatorKeyList) { if (StringUtils.isBlank(receiverKey)) { continue; } // 所有类型通知数量 long getNonReadNofificationCount = notificationMapper.getNonReadNofificationCount(receiverKey); WsMessageTermEnum term = WsMessageTermEnum.valueOf(EtcConstant.notificationTerm); String receiverKeyTerm = EtcConstant.getKey(receiverKey, term); WsMessageEntity wsMessageEntity = new WsMessageEntity(WsMessageTypeEnum.message, receiverKeyTerm); wsMessageEntity.setBody(getNonReadNofificationCount); wsMessageEntity.setBodyClazz(EtcConstant.WsMessage.AlarmCount); AbstractWebSocketServer.sendMsg(receiverKeyTerm, wsMessageEntity); // 各个类型通知数量 List<LabelNonReadNofificationCountDO> labelNonReadNofificationCountList = notificationMapper.getLabelNonReadNofificationCount(receiverKey); Map<String, Integer> labelNonReadNofificationCount = new HashMap<>(); for (LabelNonReadNofificationCountDO labelNonReadNofificationCountDO : labelNonReadNofificationCountList) { labelNonReadNofificationCount.put(labelNonReadNofificationCountDO.getType().name(), labelNonReadNofificationCountDO.getAmount()); } wsMessageEntity.setBody(labelNonReadNofificationCount); wsMessageEntity.setBodyClazz(EtcConstant.WsMessage.labelNonReadNofificationCount); AbstractWebSocketServer.sendMsg(receiverKeyTerm, wsMessageEntity); } }
- 推送通知
- RedisConfig(继承CachingConfigurerSupport)
- JedisPool
- JedisPoolConfig
@Bean public JedisPool redisPoolFactory() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(maxTotal); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMinIdle(minIdle); jedisPoolConfig.setMaxWaitMillis(maxWaitMillis); return new JedisPool(jedisPoolConfig, host, port, timeout, password); }
- JedisPoolConfig
- RedisTemplate
- StringRedisTemplate
private static final ObjectMapper om = new ObjectMapper(); @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); stringRedisTemplate.setValueSerializer(jackson2JsonRedisSerializer); stringRedisTemplate.afterPropertiesSet(); return stringRedisTemplate; } - Jackson2JsonRedisSerializer
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om);
- StringRedisTemplate
- MessageListenerAdapter
- RedisMessageListenerContainer
- MessageListener
- PatternTopic
- JedisPool
- 定义观察者RedisReceiver(实现org.springframework.data.redis.connection.MessageListener)
- 定义通知推送的终端
- notificationTerm=mech
- Filter
- 获取WS子协议
- String token = request.getHeader("Sec-WebSocket-Protocol");
- response.setHeader("Sec-WebSocket-Protocol", token);
- 获取WS子协议
- AbstractWebSocketService
- javax.websocket.Session
- @OnOpen
- @OnMessage
- @OnError
- @OnClose
- session.getBasicRemote().sendText(String text) throws IOException;
- WebSocketServiceImpl
- @Component
- @ServerEndpoint(value = "/ws/imServer/{term}")
- 啦啦啦
相关推荐
springboot整合WebSocket
springboot整合WebSocket WebSocket通信过程 客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的候,会向服务端发送一个http get报文,告诉服务端需要将通信协议切换到websocket,服务端收到http请求后将通信协议切换到websocket,同时发给客户端一个响应报文,返回的状态码为101,表示同意客户端协议转请求,并转换为websocket协议。以上过程都是利用http通信完成的,称之为websocket协议握手(webs
Spring boot Websocket 添加授权校验(校验Header)
继承ServerEndpointConfig.Configurator 并重写modifyHandshake方法,在这里拦截header中Authorization的内容,并将其设置到websocket session 中。获取之前设置入session中的Authorization信息,这里为了方便,仅仅只是校验了有没有传入,没有传入则代表校验失败。取消送入header内容Authorization时,连接先成功,后失败,则代表已经连接到服务器,但因为校验失败,被断开了连接。
SpringBoot整合WebSocket遇到的坑
websocket failed: Error during WebSocket handshake: Unexpected response 1、pom.xml 中引入 spring-boot-starter-websocket <dependency> <groupId>org.springframework.boot</groupId> ...
springboot+vue整合websocket(含鉴权)
springboot+vue+websocket 包含spring security鉴权
SpringBoot整合WebSocket服务
1、前言注意: 仅使用 SpringBoot封装好的 spring-boot-starter-websocket 服务,并不是使用第三方 Netty或者 Apache MINAspring-boot-starter-web: 底层使用 Java WebSocket API (JSR-356)实现spring-boot-starter-webflux: 底层使用 Netty实现(没有使用过,不知道具体)官方文档1官方文档22、开始使用2.1、加入Maven依赖。
websocket-protocol:websocket协议
近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应用。在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。 轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服
【websocket】使用websocket实现springboot与浏览器的通信
网上翻了很多介绍的使用方法都是没有请求头条件下使用的,但是为了安全问题一般都会加上请求头进行验证,这是携带token进行连接的方法
命令行删除描述文件_写一个删除lock文件的skill脚本
来源:IC技能搬运工 作者:小目Cadence软件使用过程中偶尔会遇到文件被lock的情况,这是Cadence软件对文件的一种保护措施,大部分情况都是对用户友好的,但是偶尔也会给用户带来困扰,给工作带来的一定的不便。文件是如何被锁的Cadence在用户打开文件进行编辑的时候会在文件的同一级目录新建一个lock文件,用来标识文件的状态。一般情况下如果文件被正常关闭,这个lock文件会在...
Spring Boot WebSocket 客户端_springboot创建websocket客户端
外链图片转存中…(img-MoMKOEeI-1712914457688)]
IoT 平台架构全景图:从设备到 AI 的完整技术体系深度解析
随着物联网设备规模进入百万级时代,IoT 平台架构已经从简单的设备接入系统演变为完整的数据平台。本文从系统架构师视角,深度解析 IoT 平台的完整技术体系,包括设备接入、MQTT 通信、消息流平台、数据平台与 AI 决策系统,并结合主流云平台实践,构建从设备到 AI 的完整 AIoT 架构认知。
Keil MDK打开别人工程总报错?手把手教你修复‘找不到main.o’和‘未定义’的路径问题
本文详细解析Keil MDK工程移植时常见的'找不到main.o'和'未定义'编译错误,提供从路径修复到宏定义配置的完整解决方案。通过系统化的检查清单和预防措施,帮助开发者快速解决MDK工程迁移问题,提升嵌入式开发效率。
spring boot学习第六篇:SpringBoot 集成WebSocket详解
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
软件测试方法——等价类划分法详解
!如果下面这些资料用得到的话可以直接拿走:1、自学开发或者测试必备的完整项目源码与环境2、测试工作中所有模板(测试计划、测试用例、测试报告等)3、软件测试经典面试题4、Python/Java自动化测试实战.pdf5、Jmeter/postman接口测试全套视频获取6、Python学习路线图。
Springboot集成websocket
Springboot集成websocket
Windows版本Carla(含RoadRunner插件)源码安装+RoadRunner地图导入
通过跳转浏览器账号密码登录github,不要选择Fine-grained personal access tokens,在git clone时会显示非授权,也不要使用Windows凭据!核心指令:编译PythonAPI–make PythonAPI,,编译Server–make launch,封装”游戏“–make package。完成安装后,在已安装->2022版本右侧->更多->导入配置,选择配置文件(需将配置文件内容更新为手册内容,如下图)->详细信息,更新。不要修改版本,执行上面指令即可!
脑影像分析软件推荐 | JuSpace
JuSpace是一种允许基于 MRI 测量与核成像衍生估计的跨模态关联的工具包,它涵盖各种神经递质系统,包括多巴胺能、血清素能、去甲肾上腺素能和 GABA(γ-氨基丁酸) 神经传递。JuSpace 由一组 Matlab 功能以及涵盖各种受体系统的 PET 受体图谱组成。
SpringBoot实现WebSocket
WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议) 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。
103.在 Vue 3 中使用 OpenLayers 控制图层来显示/隐藏地图
是一个强大的开源库,可以用于构建各种地理信息系统应用。在 Vue 3 中,我们可以结合。方法,可以直接控制某个图层是否可见,而不需要删除或重新创建图层。在开始之前,确保你已经搭建了 Vue 3 项目,并安装了。本文将详细介绍如何在 Vue 3 组合式 API (,并实现按钮控制地图的显示/隐藏功能。会导致 OSM 瓦片地图无法加载。方法控制地图图层的显示与隐藏。安装完成后,即可开始编写代码。在本教程中,我们介绍了如何在。来实现地图的显示/隐藏功能。来实现交互式地图,并通过。在 WebGIS 开发中,
SpringBoot整合WebSocket
一、WebSocket与Http的区别 HTTP是应用层上的一个单向的、无状态的、基于请求与响应的协议。http协议本身是没有持久通信能力的,当客户端向服务器发送HTTP请求时,接收到请求后,服务器会将响应发送给客户端。每个请求都与一个对应的响应相关联,在发送响应后客户端与服务器的连接会被关闭。这种的基于请求响应的通讯方式有一点不足,服务器端无法主动向客户端推送数据。 Websocket是应用层上的一个全双工的有状态协议。websocket以ws://或wss://开头,它必须依赖 HTTP 协议进行一次
【大模型应用开发-FastAPI框架】(八)Sqlalchemy+postgresql简单增删改查
语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型”。SQLAlchemy的理念是,的量级和性能重要于对象集合;而对象集合的抽象又重要于表和行。因此,SQLAlchemy采用了类似于。社区中成为广泛使用的ORM工具之一,不亚于Django的ORM框架。和declarative等可选插件可以让用户使用声明语法。SQLAlchemy首次发行于2006年2月,并迅速地在。SQLAlchemy“采用简单的。二、安装postgresql。一、SQLAlchemy简介。的数据映射模型,而不是其他。
IEM模型,地表粗糙度模拟
利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟
spring boot websocket 客户端_SpringBoot集成websocket
第一种:SpringBoot官网提供了一种websocket的集成方式第二种:javax.websocket中提供了元注解的方式下面讲解简单的第二种添加依赖<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-...
ET2012新版免狗免安装绿色软件
ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,
springboot集成websocket
这里我们使用springboot搭建一个轻量级的websocket服务,同时提供4个入参。使用websocket服务可以轻松和微信小程序、支付宝小程序、网页就行双向通讯,非常实用方便。wss地址这里是我们自己搭建的中转服务websocket地址。参数说明。
Outlook Express 6 (OE6) for Win7/Win8/Win10
英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
spring boot 搭建websocket_WebSocket 整合 Springboot
WebSocket+Springboot1.1 pom 文件的依赖和插件<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE<...
springboot websocket 原理。
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许服务器和客户端之间进行实时数据交换。Spring Boot 通过集成 Spring WebSocket 模块,简化了 WebSocket 的实现。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许服务器和客户端之间进行实时数据交换。Spring Boot 通过集成 Spring WebSocket 模块,简化了 WebSocket 的实现。WebSocket 协议通过 HTTP 协议升级实现。
Springboot整合WebSocket
Springboot整合WebSocket实现点对点、订阅式消息通知,附完整源码
2万+



被折叠的 条评论
为什么被折叠?



