导入maven依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

配置websocket

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
@EnableWebSocketMessageBroker  //注解开启STOMP协议来传输基于代理的消息,此时控制器支持使用@MessageMapping
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic", "/user");//topic用来广播,user用来实现p2p//点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/config.setUserDestinationPrefix("/user");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {//使用sockjs兼容pc端各大浏览器(微信小程序连接不了)registry.addEndpoint("/webServer").setAllowedOrigins("*").addInterceptors().withSockJS();//小程序连接,重点在withSockJS()registry.addEndpoint("/wxServer").setAllowedOrigins("*").addInterceptors();}}

发送消息(点对点)

    @Autowiredpublic SimpMessagingTemplate messagingTemplate;@GetMapping("/send/test1")public Result sendTest1() {MsgCarrier carrier = MsgCarrier.build().withType(MessageType.ORDER_CONFIRM).withMsg("发送单人成功").withData(new Date());messagingTemplate.convertAndSendToUser("123456", "/wx/push/singleton", carrier);return Result.success("发送成功!");}

发送消息(一对多)

    @Autowiredpublic SimpMessagingTemplate messagingTemplate;public Result sendTest2() {MsgCarrier carrier = MsgCarrier.build().withType(MessageType.ORDER_CONFIRM).withMsg("发送多人成功").withData(new Date());messagingTemplate.convertAndSend("/topic/wx/push/all", carrier);return Result.success("发送成功!");}

##在线人数计数器

import org.springframework.stereotype.Component;/*** 在线人数计数器(线程安全)** @Author xs* @Date 2019/4/23 10:43*/
@Component
public class Counter {private Long onlineCount = 0L;/*** 在线人数增长*/public synchronized void incrementCount(){onlineCount++;}/*** 在线人数减少*/public synchronized void decrementCount(){onlineCount--;}/*** 获取在线人数* @return 在线人数*/public Long getOnlineCount(){if(this.onlineCount <= 0){return 0L;}return this.onlineCount;}}

消息载体实体类

import com.yikesong.favourablelife.pojo.enums.MessageType;import java.io.Serializable;
import java.util.Date;/*** websocket 消息载体** @Author xs* @Date 2019/6/15 11:01*/
public class MsgCarrier implements Serializable {private MessageType type;//消息类型private String msg;//消息内容private Object data;//消息载体数据private Date time;//消息时间public Date getTime() {return time;}public void setTime(Date time) {this.time = time;}public MessageType getType() {return type;}public void setType(MessageType type) {this.type = type;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public static MsgCarrier build() {MsgCarrier msgCarrier = new MsgCarrier();msgCarrier.setTime(new Date());return msgCarrier;}public MsgCarrier withType(MessageType type) {this.type = type;return this;}public MsgCarrier withData(Object data) {this.data = data;return this;}public MsgCarrier withMsg(String msg) {this.msg = msg;return this;}public MsgCarrier withTime(Date time) {this.time = time;return this;}}

小程序端代码实现

1.Socket工具类(重连机制)
/* Created by zfh on 2018/11/2 */
import { Stomp } from "./stomp";class WebSocket {/*** 微信 WebSocket 任务*/socketTask = null;/*** Stomp代理*/stompClient = null;/*** 默认监听的消息频道*/channel = null;/*** 消息监听器*/messageMonitor = null;/*** 消息处理器*/messageHandler = null;/*** 重连成功的回调*/reconnectCallback = null;/*** 主动断开连接的标识*/disconnectFlag = false;/*** 默认最大重连次数*/RECONNECT_MAX_COUNT = 50;/*** 默认重连时间间隔(单位:ms)*/RECONNECT_TIME_INTERVAL = 1500;/*** 断线重连计数*/RECONNECT_COUNT = 0;constructor() {/*setInterval是用来发心跳包的,而小程序没有window对象*/Stomp.setInterval = function (interval, f) {return setInterval(f, interval);};Stomp.clearInterval = function (id) {return clearInterval(id);};}/*** 建立websocket连接和频道监听,绑定消息处理器* @param header            消息头* @param webSocketUrl      连接地址* @param channel           监听的频道* @param messageHandler    消息处理器* @param reconnectCallback 成功回调*/bulidConnectAndMonitor(header, webSocketUrl, channel, messageHandler, reconnectCallback) {var that = this;if (!this.getSocketStatus()) {var socketTask = wx.connectSocket({url: webSocketUrl});var ws = {send: function (frame) {socketTask.send({ data: frame });},close: function (frame) {socketTask.close(frame);}};socketTask.onOpen(function (frame) {ws.onopen(frame);if (that.RECONNECT_COUNT > 0) {that.reconnectCallback()}that.RECONNECT_COUNT = 0;console.log("websocket连接成功");});socketTask.onMessage(function (frame) {ws.onmessage(frame);});socketTask.onClose(function (frame) {that.stompClient._cleanUp();/*客户端主动断开连接,不启动重连。*/if (that.disconnectFlag) {that.disconnectFlag = false;console.log("websocket断开连接");return;}/*因为是递归,所以使用setTimeout()来做定时器*/setTimeout(function () {that.RECONNECT_COUNT += 1;console.log("重连次数:", that.RECONNECT_COUNT);if (that.RECONNECT_COUNT >= that.RECONNECT_MAX_COUNT) {console.log("websocket连接失败");return;}that.bulidConnectAndMonitor({}, webSocketUrl, that.channel, that.messageHandler, that.reconnectCallback);}, that.RECONNECT_TIME_INTERVAL);});var stompClient = Stomp.over(ws);that.stompClient = stompClient;stompClient.connect(header,function () {that.messageMonitor = stompClient.subscribe(channel, messageHandler);that.socketTask = socketTask;that.channel = channel;that.messageHandler = messageHandler;that.reconnectCallback = reconnectCallback;reconnectCallback('默认通道已开启');console.log("默认监听的频道:", channel);});}}/*** 设置默认消息监听器* @param messageHandler    消息处理器* @param reconnectCallback 重连成功的回调*/setDefaultMessageMonitor(messageHandler, reconnectCallback) {if (this.getSocketStatus()) {this.removeDefaultMessageMonitor();this.messageMonitor = this.stompClient.subscribe(this.channel, messageHandler);/*更新消息处理器*/this.messageHandler = messageHandler;/*更新重连的回调*/this.reconnectCallback = reconnectCallback;console.log("默认监听频道:", this.channel);}}/*** 移除默认消息监听器*/removeDefaultMessageMonitor() {if (this.getSocketStatus()) {this.messageMonitor.unsubscribe();console.log("The default listener was removed successfully");}}/*** 自定义消息监听器* @param channel         监听的频道* @param messageHandler  消息处理器* @return messageMonitor 消息监听器*/addMessageMonitor(channel, messageHandler) {console.log("addMessageMonitor Socket状态",this.getSocketStatus());if (this.getSocketStatus()) {console.log("新监听频道:", channel);return this.stompClient.subscribe(channel, messageHandler);}}/*** 移除消息监听器* @param messageMonitor 消息监听器*/removeMessageMonitor(messageMonitor) {if (messageMonitor == null || JSON.stringify(messageMonitor) === '{}') {console.log("监听器不能为空");return;}if (this.getSocketStatus()) {messageMonitor.unsubscribe();console.log("The listener was removed successfully");}}/*** 发送消息* @param channel 频道* @param header  消息头* @param body    消息体*/sendMessage(channel, header, body) {if (this.getSocketStatus()) {this.stompClient.send(channel, header, JSON.stringify(body));}}/*** 关闭连接*/close() {if (this.getSocketStatus()) {this.stompClient.disconnect();this.disconnectFlag = true;}}/*** 获取连接状态* @return boolean*/getSocketStatus() {var boolean = false;if (this.socketTask && this.socketTask.readyState) {boolean = this.socketTask.readyState === 1;}console.log("websocket连接状态:" + boolean);return boolean;}
}export {WebSocket
}
2.简单使用
import { WebSocket} from '../utils/Socket'
Page({data: {},onLoad: function () {let socket = new WebSocket();socket.bulidConnectAndMonitor({}, 'ws://127.0.0.1:9101/wxServer','/topic/wx/push/all',function(body){//接收广播频道console.log(body);},function(con){console.log(con);//添加一对一频道socket.addMessageMonitor("/user/123456/wx/push/singleton", function (body) {console.log(body);});});

PC端连接Socket(sockjs兼容)

1.下载sockjs依赖
cnpm i sockjs --save
2.引入sockjs以及stomp
import SockJS from "sockjs-client";
import Stomp from "stompjs";
3.创建sicket连接
//scoket
initWebSocket() {this.connection();
},
connection() {//创建连接var _this = this;// 建立连接对象let socket = new SockJS(this.webSocketUrl);// 获取STOMP子协议的客户端对象this.stompClient = Stomp.over(socket);// 定义客户端的认证信息,按需求配置let headers = {Authorization: ""};// 向服务器发起websocket连接this.stompClient.connect(headers,frame => {if (this.connectLock) {console.log("锁线程锁已还原");clearInterval(this.timer);this.connectLock = false; //还原锁}//点对点接收消息this.stompClient.subscribe(`/user/${this.userInfo.id}/spell/order`,msg => {});//一对多订阅消息this.stompClient.subscribe("/topic/super/to/agent", msg => {});},err => {// 连接发生错误时的处理函数console.log("连接失败...");if (!this.connectLock) {this.reconnect();}});
}, //连接 后台
disconnect() {if (this.stompClient) {this.stompClient.disconnect();}
}, // 重新连接
reconnect() {let that = this;if (this.connectLock) return;this.connectLock = true;// 断开重连机制,尝试发送消息,捕获异常发生时重连this.timer = setInterval(() => {that.connection();}, 5000);
},
validateToken() {let token = getToken();if (!token) {console.log("未登录,关闭连接");if (this.timer) {clearInterval(this.timer);}this.connectLock = false; //还原锁//断开连接console.log("连接已断开");}
},

这种方式既可以兼容PC端的Socket连接,又可以实现单个需求的socket连接(如微信小程序)

Springboot+Websocket+Stomp实现PC兼容,及微信小程序连接相关推荐

  1. java大型多店铺商城源码java多店铺商城系统b2b2c, b2 springboot架构。支持pc+h5+小程序+安卓app+苹果app

    java大型多店铺商城源码java多店铺商城系统b2b2c, b2 springboot架构.支持pc+h5+小程序+安卓app+苹果app

  2. Qt QWebsocket实现SSL后台服务程序 和微信小程序连接使用

    Qt QWebsocket实现SSL后台服务程序 和微信小程序连接使用 --Qt QWebsocket SSL wss 微信小程序 前言 微信小程序是不支持https和wss以外的远程通信接口的,这给 ...

  3. 微信小程序连接emqx服务器实现数据交互

    微信小程序连接emqx服务器实现数据交互 emqx 申请链接 EMQX 是一款全球下载量超千万的开源物联网MQTT 服务器,高效可靠连接海量物联网设备,高性能实时处理消息与事件流数据,可运行在公有云. ...

  4. 微信小程序连接蓝牙打印机打印图片示例

    微信小程序连接蓝牙打印机示例 完整的代码示例请点击看github 小程序连接蓝牙打印机打印文本与二维码等示例在 github 上都能找到一些,唯独打印图片这个案例几乎没有.希望能帮助到有打印图片需求的 ...

  5. 微信小程序连接物联网(二):NodeMCU Lua学习笔记

    索引 这是用微信小程序遥控开门的系列文章,具体微信小程序连接物联网的代码在第三章提及. 微信小程序连接物联网(一):初始化ESP8266 NodeMCU 微信小程序连接物联网(二):NodeMCU L ...

  6. 微信小程序连接mysql

    我在想用微信小程序连接mysql的时候想在网上找个教程结果发现教程很少而且都非常的麻烦,我一直试了好几天,终于是用一种简单的方法搞定了,发个博客总结一下,顺便让大家少走一些弯路. 1.服务器搭建 首先 ...

  7. 微信小程序连接MySQL数据库

    微信小程序连接MySQL数据库 简要说明: 承接上一个商品列表页,在服务器端连接MySQL数据库,通过条件匹配查寻数据并显示在客户端 准备工作 1.node.js 2.微信开发者工具 3.MySQL数 ...

  8. 微信小程序连接蓝牙ble教程(目录)

    微信小程序连接蓝牙教程(目录) 1.新建小程序项目 2.初始化蓝牙适配器(wx.openBluetoothAdapter) 3.获取蓝牙适配器状态(getBluetoothAdapterState) ...

  9. 微信小程序连接阿里云物联网平台——物联网远程控制开发1

    博主在尝试使用微信小程序与阿里云物联网平台的topic通信,但有些资源说的不够详细,容易搞懵小白,因此补充一些. 内容框架参考: [物联网]微信小程序接入阿里云物联网平台 微信小程序连接阿里云物联网平 ...

最新文章

  1. java spring-webflux netty
  2. springboot python 开发效率比较-2018年Java开发值得学习的10大技术
  3. Java常用设计模式————抽象工厂模式
  4. 正确加载 Javascript 和 CSS 到 WordPress
  5. 不用空格怎么打两个空格_韩语空格怎么空?90%的韩语初学者都会出错!
  6. Nancy 框架学习
  7. 上网爱快?EasyRadius FOR 爱快V2接口测试版正式推出,欢迎广大爱迷们测试噢
  8. 早期微信抢红包插件项目分享
  9. 3D 旋转相册 立方体的盒子 相册(源码分享)
  10. 高分三号卫星(GF-3)简介
  11. 【ResNet】Deep Residual Learning for Image Recognition (2015) 全文翻译
  12. 2.13navigation导航系统
  13. 毁三观:妻妹把我压身下
  14. 英语句子主干成分分析
  15. thinkadmin打印sql语句调试sql
  16. ( 持续更新,目前含 200+ 工具类 ) DevUtils 是一个 Android 工具库, 主要根据不同功能模块,封装快捷使用的工具类及 API 方法调用。
  17. 建成 5000 多间「梦想中心」后,他们决定将技术开源
  18. 真实感受一下县比省大不包邮,省市区乡镇多级数据重装上阵
  19. 20世纪最好的10个算法
  20. iOS进度条 自定义圆角 UIProgressView

热门文章

  1. form表单提交数据,处理后端返回数据
  2. 客户服务:提供有效客户客服的几种方法
  3. 如何培养解决复杂问题的能力
  4. 魏永明: 三谈操作系统
  5. 数据分析Demo:广告点击数据分析
  6. 成都创弘星鹏:怎样办理抖音小店的营业执照
  7. 《洗脑术:怎样有逻辑地说服他人》
  8. Linux——常用命令(基本权限)
  9. 人像摄影技巧——镜头差异可改变脸部印象
  10. Akamai阿卡迈_abck逆向sensor_data(二)