WebSocket的定义:

WebSocket 是独立的、创建在 TCP 上的协议。

Websocket 通过HTTP/1.1 协议的101状态码进行握手。

为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”

浏览器发出请求


GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== //浏览器随机生成的Base64 加密值
Sec-WebSocket-Protocol: chat, superchat     //用户定义的字符串, 用来区分相同url下, 不同服务所需要的协议
Sec-WebSocket-Version: 13                  //版本
Origin: http://example.com

服务器响应请求


HTTP/1.1 101 Switching Protocols
Upgrade: websocket  //已经成功切换websocket协议
Connection: Upgrade //已经成功切换websocket协议
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了

引入依赖

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

WebSocketController

import cn.gzccc.wx.expertUser.domain.WxExpertUser;
import cn.gzccc.wx.expertUser.service.IWxExpertUserService;
import cn.gzccc.wx.utils.SecurityUtils;
import cn.gzccc.wx.utils.SpringContextUtil;
import cn.hutool.crypto.CryptoException;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;@Slf4j
@Component/*** 微信小程序聊天的websocket* token --> 微信小程序用户openId Aes加密后的Hex密文*/
@ServerEndpoint("/wx/api/websocket/{token}") //@ServerEndpoint主要是将目前的类定义成一个websocket服务器端,//注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
public class WebSocketController {/***  与某个客户端的连接对话,需要通过它来给客户端发送消息*/private Session session;/*** 标识当前连接客户端的用户标识*/private String token;/***  用于存所有的连接服务的客户端,这个对象存储是安全的*/public static ConcurrentHashMap<String, WebSocketController> map = new ConcurrentHashMap<>();public ConcurrentHashMap<String, WebSocketController> content(){return map;}/*** 连接建立成功调用的方法** @param session 与某个客户端的连接会话,需要通过它来给客户端发送数据* @param token   用户token*/@OnOpenpublic void onOpen(Session session, @PathParam(value = "token") String token){// 判断当前token 是否属于User中所存在的真实用户this.session = session;this.token = token;if (isUser()){map.put(this.token,this);log.info("[WebSocket] 连接成功,当前连接人数为:={}", map.size());appointSending(token,"连接成功");}else{map.put(this.token,this);log.info("[WebSocket] 异常用户连接,token为:={}", this.token);appointSending(token,"异常用户,已记录该行为");map.remove(this.token);}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(){// 设置该用户下线String openId = SecurityUtils.decryption(token); //解密IWxExpertUserService wxExpertUserService = SpringContextUtil.getContext().getBean(IWxExpertUserService.class);WxExpertUser wxExpertUser = wxExpertUserService.selectWxUserByOpenId(openId);if (wxExpertUser !=null){wxExpertUser.setOnline(0); //设置下线wxExpertUserService.updateWxExpertUser(wxExpertUser);}map.remove(this.token);log.info("[WebSocket] 退出成功,当前连接人数为:={}", map.size());}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message){if (isUser()){try{ObjectMapper mapper =new ObjectMapper();Message mess = null;try{mess = mapper.readValue(message, Message.class);}catch (Exception e){// 用户付费时间已过期map.put(this.token,this);appointSending(token,"消息格式错误,无法为您转发信息");map.remove(this.token);}// 设置发送者mess.setSendToken(this.token);String toToken = mess.getToToken(); // 获取接收者TokenString messageContent = mess.getMessageContent(); // 获取消息内容String messageType = mess.getMessageType(); // 获取消息类型JSONObject jsonObject = new JSONObject();jsonObject.set("sendToken",mess.getSendToken());jsonObject.set("toToken",mess.getToToken());jsonObject.set("messageType",mess.getMessageType());jsonObject.set("messageContent",mess.getMessageContent());String json = jsonObject.toString();// websocket提供了发送信息的方法appointSending(toToken,json);}catch (Exception e){e.printStackTrace();}}else{map.put(this.token,this);appointSending(token,"您的账号不存在,系统无法为您传达此信息");map.remove(this.token);}log.info("[WebSocket] 收到消息:{}","发送者Token:" + this.token + "," + message);}/*** 发生错误时调用* * @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error){error.printStackTrace();}/*** 指定发送** @param token    用户token* @param message  要发送的信息*/public void appointSending(String token,String message){// 判断token 是否在线if (!"连接成功".equals(message)) {WebSocketController webSocketController = map.get(token);if (webSocketController == null){// 不在线 公众号发送消息log.info("指定发送 message: "+message);//sendWxTemplate(message,token);}}try {if (map.get(token) != null) {// websocket提供了发送信息的方法, this.session.getBasicRemote()对象的方法.map.get(token).session.getBasicRemote().sendText(message);}}catch (Exception e){e.printStackTrace();}}/*** 判断当前用户是否存在* @return*/public boolean isUser(){try{String openId = SecurityUtils.decryption(token); //解密IWxExpertUserService wxExpertUserService = SpringContextUtil.getContext().getBean(IWxExpertUserService.class);WxExpertUser wxExpertUser = wxExpertUserService.selectWxUserByOpenId(openId);if (wxExpertUser == null){return false;}else{// 设置该用户上线wxExpertUser.setOnline(1);wxExpertUserService.updateWxExpertUser(wxExpertUser);return true;}}catch (CryptoException e){return false;}}
}

SecurityUtils

import cn.hutool.crypto.symmetric.AES;public class SecurityUtils {// 加密public static String encryption(String data){AES aes = new AES("CBC", "PKCS7Padding",// 密钥,不可更改"GzcccPCall012345".getBytes(),// iv加盐"GzcccCallDYgjCE0".getBytes());// 加密为16进制表示String encryptHex = aes.encryptHex(data);return encryptHex;}// 解密public static String decryption(String data){AES aes = new AES("CBC", "PKCS7Padding",// 密钥,不可更改"GzcccPCall012345".getBytes(),// iv加盐"GzcccCallDYgjCE0".getBytes());// 加密为16进制表示String decryptStr = aes.decryptStr(data);return decryptStr;}}

 微信线上小程序测试

打开小程序 

退出小程序 

springboot整合websocket实现微信小程序聊天相关推荐

  1. [微信小程序]聊天对话(文本,图片)的功能(完整代码附效果图)

    相关文章: 1.小程序聊天群,发送语音,文字,图片. 2.微信小程序集成腾讯IM,实现实时音视频通话,1V1聊天 3.云开发微信小程序聊天群 4.接入网易云信IM即时通讯的微信小程序聊天室 5.微信小 ...

  2. 云开发微信小程序聊天群

    功能支持创建群,邀请群成员,群成员列表展示,图片发送,设置群公告,踢人,全体禁言,个人禁言,发送语音信息等 相关文章: 1.小程序聊天群,发送语音,文字,图片. 2.微信小程序集成腾讯IM,实现实时音 ...

  3. 基于springboot高校闲置物品交易系统微信小程序源码和论文

    基于springboot二手物品交易系统微信小程序 互联网的兴起从本质上改变了整个社会的商品交易方式,国内各大企业从上个世纪 90 年代互联网兴起之时,就产生了通过网络进行销售经营商品的想法.但是由于 ...

  4. (附源码)springboot人体健康检测微信小程序 毕业设计 012142

    Springboot人体健康检测微信小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的人体健康检测小程序,主要为人们提供了方便的各项健康检测服务,包括健康数据编辑.健康科普.健康讨论.注册登录 ...

  5. 微信小程序聊天语料收集平台技术总结

    最近接了个项目要求要做微信小程序聊天的,似乎和实验室收集语料数据有关,这里对要用到的技术简单做个记录,主要怕自己忘记了. 估计项目需要很多个GitHub模块聚合在一起 模块1:聊天室 目前先部署了 e ...

  6. 基于spring-boot的社区社交微信小程序,适合做脚手架、二次开发

    代码地址如下: http://www.demodashi.com/demo/13867.html 1 概述 笔者做的一个后端基于spring-boot的社区社交微信小程序,可以作为开发的脚手架,开发速 ...

  7. Springboot简便的配置微信小程序

    Springboot简便的配置微信小程序 ShareNotes 最近在完成一个微信小程序项目,即将上线 欢迎star Github–ShareNotes issue 写小程序接口遇到的具体情况 通过o ...

  8. NLP微信小程序聊天机器人

    今天把两年前大二时候的小程序又拿来玩了一下,决定开源这个小项目 一个NLP微信小程序聊天机器人,前端就一个页面,后端是php的,可以接图灵等等各种api,也可以自己写个python的接口做NLP算法测 ...

  9. java+SpringBoot+HTML+Mysq基于微信小程序的掌上博物馆游览

    详细功能设计:请点击下面链接查看 java+SpringBoot+HTML+Mysq基于微信小程序的掌上博物馆游览_哔哩哔哩_bilibili 源码+论文获取: 源码+论文获取请私信获取 摘  要 本 ...

  10. 可视化uniapp整合thinkphp6实现微信小程序支付

    可视化uniapp整合thinkphp6实现微信小程序支付,调用tp6接口返回微信相关下单参数. 开源代码:diygw-ui-php: diygwUI+Thinkphp6实现PHP后台框架 //微信小 ...

最新文章

  1. 在ASP.Net中如何彻底杀死Excel进程
  2. iOS开发网络篇—搭建本地服务器(待整理)
  3. 2017沈阳站流水账+感想
  4. Mybatis 基础 定义别名,属性配置
  5. 一次远程支持事故的教训,与大家分享
  6. 家用电器用户行为分析与事件识别代码详解+修改后运行无误的代码
  7. SAP Fiori gateway OData开发重要的tcode SEGW背后的数据库表
  8. 第44课 角谷猜想 动动脑 第3题 完善程序
  9. php文件上传接口测试,七牛云存储-用php上传图片,我在本地测试,用php接口,不成功...
  10. Npm常用命令有哪些
  11. 进程间通信 - 整理
  12. CEF与快速交换的比较
  13. Unity3D 在 UI TextMeshPro (TMP) 中显示中文
  14. idea 检测 重复代码_重复代码检测
  15. 基于canvas的图片反色处理
  16. RTL设计基础(一)
  17. 五个顶级的大数据架构
  18. php更改文件为只读,word只读模式怎么修改
  19. 解压缩SIS文件工具
  20. html 缩小时字体错位,微信字体设置导致页面错位的解决方法

热门文章

  1. html5二维动画教程,Flash二维动画制作案例教程
  2. 下载Cisco Packet Tracer 模拟器 含汉化教程
  3. java如何使用移位运算符_JAVA移位运算符使用教程
  4. linux镜像添加驱动,添加raid驱动到initrd.img
  5. php 关闭call stack,Thinkphp Call Stack,PHP调用栈Call Stack的获取
  6. 成绩查询系统源代码-Leo老师
  7. 献给青春的歌 · 致「 腾讯QQ 18 岁」
  8. creo图纸管理系统 creo企业图纸管理方案
  9. 用友打印问题合集 二【各模块】
  10. Axure RP从入门到精通(二十)鼠标指针函数