1、什么是WebSocket

  WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向

客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

  在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。HTML5 定

义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

  2、实现原理

  可以看到,浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。第一次握手是基

于HTTP协议实现的,当获取 Web Socket 连接后,就可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

  3、具体实现

  WebSocket的优点不言而喻,下面直接上代码。

  1、首先创建一个springboot项目,网上教程很多,也可以参考楼主的创建SpringBoot项目,很简单,最终的目录结构如下:

 2、项目的pom.xml如下:

  

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.winmine</groupId><artifactId>WebSocket</artifactId><version>0.0.1-SNAPSHOT</version><name>WebSocket</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.46</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

  引入WebSocket的标签就是:

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

  3、application.properties中配置端口号,楼主的是22599的端口号。

server.port=22599

  4、配置类

  

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {/*** ServerEndpointExporter 作用** 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint** @return*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

  5、核心类

  

 
package com.winmine.WebSocket.service;import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;@ServerEndpoint("/webSocket/{sid}")
@Component
public class WebSocketServer {//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。private static AtomicInteger onlineNum = new AtomicInteger();//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();//发送消息public void sendMessage(Session session, String message) throws IOException {if(session != null){synchronized (session) {
//                System.out.println("发送数据:" + message);session.getBasicRemote().sendText(message);}}}//给指定用户发送信息public void sendInfo(String userName, String message){Session session = sessionPools.get(userName);try {sendMessage(session, message);}catch (Exception e){e.printStackTrace();}}//建立连接成功调用@OnOpenpublic void onOpen(Session session, @PathParam(value = "sid") String userName){sessionPools.put(userName, session);addOnlineCount();System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);try {sendMessage(session, "欢迎" + userName + "加入连接!");} catch (IOException e) {e.printStackTrace();}}//关闭连接时调用@OnClosepublic void onClose(@PathParam(value = "sid") String userName){sessionPools.remove(userName);subOnlineCount();System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);}//收到客户端信息@OnMessagepublic void onMessage(String message) throws IOException{message = "客户端:" + message + ",已收到";System.out.println(message);for (Session session: sessionPools.values()) {try {sendMessage(session, message);} catch(Exception e){e.printStackTrace();continue;}}}//错误时调用@OnErrorpublic void onError(Session session, Throwable throwable){System.out.println("发生错误");throwable.printStackTrace();}public static void addOnlineCount(){onlineNum.incrementAndGet();}public static void subOnlineCount() {onlineNum.decrementAndGet();}}
 

  6、在Controller中跳转页面

import com.winmine.WebSocket.service.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;import java.util.HashMap;
import java.util.Map;@Controller
public class SocketController {@Autowiredprivate WebSocketServer webSocketServer;@RequestMapping("/index")public String index() {return "index";}@GetMapping("/webSocket")public ModelAndView socket() {ModelAndView mav=new ModelAndView("/webSocket");
//        mav.addObject("userId", userId);return mav;}}

  7、前端代码在webSocket.html中:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>WebSocket</title></head>
<body>
<h3>hello socket</h3>
<p>【userId】:<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
<p>【toUserId】:<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>操作:<div><a onclick="openSocket()">开启socket</a></div>
<p>【操作】:<div><a onclick="sendMessage()">发送消息</a></div>
</body>
<script>var socket;function openSocket() {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else{console.log("您的浏览器支持WebSocket");//实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接var userId = document.getElementById('userId').value;// var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;var socketUrl="ws://192.168.0.231:22599/webSocket/"+userId;console.log(socketUrl);if(socket!=null){socket.close();socket=null;}socket = new WebSocket(socketUrl);//打开事件socket.onopen = function() {console.log("websocket已打开");//socket.send("这是来自客户端的消息" + location.href + new Date());};//获得消息事件socket.onmessage = function(msg) {var serverMsg = "收到服务端信息:" + msg.data;console.log(serverMsg);//发现消息进入    开始处理前端触发逻辑};//关闭事件socket.onclose = function() {console.log("websocket已关闭");};//发生了错误事件socket.onerror = function() {console.log("websocket发生了错误");}}}function sendMessage() {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else {// console.log("您的浏览器支持WebSocket");var toUserId = document.getElementById('toUserId').value;var contentText = document.getElementById('contentText').value;var msg = '{"toUserId":"'+toUserId+'","contentText":"'+contentText+'"}';console.log(msg);socket.send(msg);}}</script>
</html>

  

  完成以上工作,就可以启动项目测试了。

  在浏览器登录系统,http://127.0.0.1:22599/webSocket

  开启socket并发送信息,后端打印:

  前端控制台打印:

  WebSocket跑通了,这是最基本的案例,把它放入自己的项目中可以按照具体业务进行改进

  PS:在开发中楼主发现部分IE浏览器的版本建立webSocket时失败,具体问题及解决方法请查看文章:

IE浏览器连接WebSocket报错:java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

SpringBoot整合WebSocket实现前后端互推消息相关推荐

  1. SpringBoot+Vue整合WebSocket实现前后端消息推送

    场景 WebSocket HTTP 协议是一种无状态的.无连接的.单向的应用层协议.它采用了请求/响应模型.通信请求只能由客户端发起,服务端对请求做出应答处理. 这种通信模型有一个弊端:HTTP 协议 ...

  2. 【Gorho】springboot整合Shiro+jwt 前后端分离 超级详细的shiro+jwt鉴权过程

    shiro+jwt+springboot 说在前面 简介 项目环境(pom.xml) 项目结构(各种包和类) 鉴权流程 具体代码 配置Shiro 配置JWTUtils 定义JwtFilter 定义Jw ...

  3. SpringBoot整合WebSocket时调用service和mapper的方法

    场景 SpringBoot+Vue整合WebSocket实现前后端消息推送: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114 ...

  4. springboot websocket_SpringBoot 集成 WebSocket 实现前后端消息互传

    WebSocket 协议是基于 TCP 的一种新的网络协议.它实现了浏览器与服务器全双工 (full-duplex) 通信-允许服务器主动发送信息给客户端. 为什么需要WebSocket? 大家都知道 ...

  5. html 监听后端变化_SpringBoot2.0整合WebSocket,实现后端数据实时推送!

    之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下. 一.什么是 ...

  6. springboot整合websocket实现消息推送

    springboot整合websocket 1.WebSocket介绍与原理 介绍:WebSocket是HTML5一种新的协议.它实现了浏览器与服务器全双工通信.一开始的握手需要借助HTTP请求完成. ...

  7. Springboot 整合Websocket+Stomp协议+RabbitMQ做消息代理 实例教程

    前言 如果你还没有了解过websocket,关于整合websocket的简单入门使用,可以先看看我这篇: <SpringBoot 整合WebSocket 简单实战案例> https://b ...

  8. SpringBoot 整合WebSocket 简单实战案例

    前言 这个简单实战案例主要目的是让大家了解websocket的一些简单使用. 另外使用stomp方式的: <Springboot 整合 WebSocket ,使用STOMP协议 ,前后端整合实战 ...

  9. Springboot 整合 WebSocket ,使用STOMP协议+Redis 解决负载场景问题(二)

    前言 上一篇,简单给大家整合了一下websocket,使用stomp方式. 这篇,就是考虑到单体的服务使用websocket ,按照上一篇的整合,确实没问题. 但是如果一旦是负载多台服务的时候,那么就 ...

最新文章

  1. Elam的git笔记:(二)git的安装与基本操作介绍
  2. ASP.NET常见错误,原因及解决方法(2003版)_不断更新.....
  3. Django集成Markdown编辑器【附源码】
  4. dns tunnel CC
  5. 详解JavaScript中ES5和ES6的类、继承之间区别和联系
  6. nagios监控mysql主从复制
  7. 专家观点:不断茁壮的音频生态系统中心(转)
  8. activemq使用
  9. plpythonu_postgresql plpythonu例子
  10. FreeRTOS源码分析与应用开发05:信号量
  11. ios 画带有箭头的线_ios纯色箭头与渐变色箭头的实现
  12. 控制面板中java设置项如何删除
  13. Dijkstra算法与Floyd算法
  14. 云计算发展趋势(二)实现云计算的技术以及其他新兴技术介绍
  15. Altair的离散元分析工具EDEM软件的2022.2版本下载与安装配置教程
  16. 【离散数学】编程练习:求关系的传递闭包
  17. 判定一棵二叉树是否是二叉搜索树
  18. PDF阅读器和编辑器选择
  19. 计算机类一级学术刊物、核心刊物列表及简介
  20. x-ray社区版简单使用教程

热门文章

  1. 编程猫海龟编辑器python_编程猫海龟编辑器
  2. Leetcode每日一题:140.word-break-ii(单词拆分)
  3. Leetcode每日一题:4.寻找两个有序数组的中位数
  4. 多目标跟踪(MOT)最新综述,一文快速入门
  5. SpringBoot App Registers UNKNOWN with Eureka in Brixton SR3
  6. 第二十二:第一个Pytest UI自动化测试实战实例
  7. 计算机关机键消失了,如何解决Windows7电脑中的关机键不见了
  8. pythonwhile循环实例 其和超过10_Python While循环语句
  9. 若依集成jsencrypt实现密码加密传输方式
  10. hbase集群 数据写入_HBase架构与原理详解