图文等内容参考链接 SpringBoot2.0集成WebSocket,实现后台向前端推送信息_Moshow郑锴的博客-CSDN博客_springboot websocket

WebSocket 简介

webSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通信的协议。

webSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在webscoket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

为什么需要 WebSocket?

初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

  • 答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

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


实现步骤

1.添加maven依赖

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

2.WebSocketConfig

启用WebSocket的支持也是很简单,几句代码搞定

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** 开启WebSocket支持*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

3.WebSocketServer

因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller。在类上添加@ServerEndpoint("/websocket") 和 @Component 注解启用

然后在里面实现 @OnOpen, @onClose, @onMessage 等方法

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.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;@Slf4j
@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。private static int onlineCount = 0;//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;//接收sidprivate String sid="";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session,@PathParam("sid") String sid) {this.session = session;webSocketSet.add(this);     //加入set中addOnlineCount();           //在线数加1log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());this.sid=sid;try {sendMessage("连接成功");} catch (IOException e) {log.error("websocket IO异常");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {webSocketSet.remove(this);  //从set中删除subOnlineCount();           //在线数减1log.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("收到来自窗口"+sid+"的信息:"+message);//群发消息for (WebSocketServer item : webSocketSet) {try {item.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}/*** * @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误");error.printStackTrace();}/*** 实现服务器主动推送,这里可能会出现并发报错,在方法上加 synchronized 就可以了*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 群发自定义消息* */public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {log.info("推送消息到窗口"+sid+",推送内容:"+message);for (WebSocketServer item : webSocketSet) {try {//这里可以设定只推送给这个sid的,为null则全部推送if(sid==null) {item.sendMessage(message);}else if(item.sid.equals(sid)){item.sendMessage(message);}} catch (IOException e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}
}

4.消息推送

至于推送新信息,可以在自己的Controller写个方法调用WebSocketServer.sendInfo();

import com.gasy.mmo.web.ws.service.WebSocketServer;
import org.springframework.web.bind.annotation.*;import java.io.IOException;@RestController
@RequestMapping("ws")
public class WsController {/*** @param sid 客户端 sid*/@GetMapping("msg/{sid}")public String wsMsg(@PathVariable("sid") String sid) {try {String msg = "*** 推送的消息内容!***";WebSocketServer.sendInfo(msg, sid); // 向连接为 {sid} 的客户端窗口发送消息} catch (IOException e) {e.printStackTrace();}return "success !!!";}}

5. web页面发起socket请求

然后在页面用js代码调用socket,当然,太古老的浏览器是不行的,一般新的浏览器或者谷歌浏览器是没问题的。还有一点,记得协议是ws的

/* WebSocket 连接 */
var wssocket;
function wsConnect() {// web模块端口:8082var WsUrl = "ws://localhost:8082/websocket/notice";    // notice 即为接口参数 sidif (typeof (WebSocket) == "undefined") {console.log("浏览器不支持WebSocket")return;}wssocket = new WebSocket(WsUrl);wssocket.onopen = function() {console.log("ws 已打开");};wssocket.onmessage = function(msg) {console.log('收到消息:' + msg.data);};wssocket.onclose = function() {console.log("ws 已关闭");};wssocket.onerror = function() {alert("ws 发生了错误");}
}

完毕

例子,我在vue.js中的发起请求的写法

<script>export default {name: "**",data() {return {socket: null,// 代码片段}},mounted() {// 代码片段/*** 页面发起socket 请求* @type {WebSocket}*/this.socket = new WebSocket("ws://localhost:8080/websocket/test");this.socket.onopen = function() {console.log("Socket 已打开");};this.socket.onmessage = function(msg) {console.log('收到消息:' + msg.data);};this.socket.onclose = function() {console.log("this.socket已关闭");};this.socket.onerror = function() {alert("Socket发生了错误");}},methods: {// 代码片段// http请求数据如下:submit: function () {    this.axios.get('url', {params:{// 向服务器传数据}}).then(res => {// 获得后台数据this.info = res.data;   /* 使用 response.data 读取 JSON 数据 */console.log(res);}).catch(function (error) {console.log(error)})},}}</script>

SpringBoot 集成 webSocket,实现后台向客户端推送消息相关推荐

  1. websocket给指定客户端推送消息

    业务场景 最近有一个业务场景是要做实时语音转义,考虑到实时性,所以决定采用websocket实现. 业务场景是A客户端(手机)进行语音转义的结果实时同步到B客户端(pc),这就需要用到websocke ...

  2. asp服务器推送消息,asp.net实时向客户端推送消息(SignalRWeb)

    [实例简介]ASP.net中服务器端向客户端推送消息,多用于在线聊天 [实例截图] [核心代码] using System; using System.Collections.Generic; usi ...

  3. springboot集成websocket(一)客户端、客户端断线重连、客户端连接验证

    springboot集成websocket客户端 一.首先是导入依赖包 1.在pom.xml中加入下述即可 <!--websocket作为客户端 --><dependency> ...

  4. 服务器向客户端推送消息之——WebSocket详细使用

    文章目录 1. 引言 2. WebSocket使用步骤 2.1 引入依赖 2.2 创建WebSocket配置类 2.3 WebSocket服务类 2.4 前端页面 1. 引言 最近遇到一个生活场景,需 ...

  5. websocket 本地可以服务器断开 springboot linux_SpringBoot+WebSocket实现简单的数据推送...

    问题背景 为什么要要用websocket呢?websocket相对于传统http协议有什么优势呢? http协议有一个缺陷,就是通信只能由客户端发起,服务器返回数据,不能做到服务器主动向客户端推送.这 ...

  6. java websocket修改为同步_服务端向客户端推送消息技术之websocket的介绍

    websocket的介绍 在讲解WebSocket前,我们先来看看下面这种场景,在HTTP协议下,怎么实现. 需求: 在网站中,要实现简单的聊天,这种情况怎么实现呢?如下图: ​ 当发送私信的时候,如 ...

  7. php 通知客户端,PHP+SSE服务器向客户端推送消息

    SSE与WebSocket作用相似,都是建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息. 但是WebSocket比SSE强大很多,SSE只能作为一个轻量级的消息推送方案,解决了从服务端向 ...

  8. DWR实现服务器端向客户端推送消息

    2019独角兽企业重金招聘Python工程师标准>>> 1.简介 DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框 ...

  9. 极光推送:java后台向APP推送消息(android,ios极光推送消息)

    Maven添加依赖 <!--极光推送--><dependency><groupId>cn.jpush.api</groupId><artifact ...

最新文章

  1. NeHe教程Qt实现——lesson15
  2. Java中父类的私有数据和静态数据在内存中是如何存储的?
  3. visual studio 正则表达式 查找与替换文本
  4. Python验证码的生成
  5. java关闭文件句柄_java-JAI关闭文件句柄为时过早吗?
  6. 常见MIME类型例表
  7. QT/Embedded 2.3.8 MX21ADS板移植
  8. PPT高级教程及技巧 .
  9. linux系统测网速工具
  10. 07.JavaScript弹窗——alert、prompt、confirm
  11. springboot 集成quartz带数据库持久化
  12. Linux查看设备端口号
  13. Vmware1个服务器2个桌面,VMware设置虚拟机,并配置远程连接桌面
  14. 电脑无法显示WLAN图标,无法联网,只有飞行模式
  15. 苹果延长13英寸MacBook Pro背光维修计划
  16. AEIA2018 | 中国工程院院士李骏:智能网联汽车的安全和自主创新是当下的关键...
  17. java-POI的Excel默认字体和样式
  18. NFS(网络文件系统)简介及搭建
  19. 微型计算机室内太干燥,暖气屋里太干燥怎么办 七种方法增加室内湿度
  20. 软件工程学生考试系统

热门文章

  1. 用Python画菱形
  2. pnpm创建vite + vue + ts项目
  3. 一段真实在个人经历 给那些迷失方向的朋友 转帖
  4. python来源介绍
  5. 自编码AE 实现图片去马赛克 pytorch
  6. C语言----用while,do-while循环求i-10的连加和,i由用户输入
  7. 别再问我MySQL为啥没走索引?就这几种原因,全都告诉你
  8. 防止程序猿和前端狗打架的几条约定
  9. 初创团队了解过的那些税
  10. 《视频直播技术详解》系列:(6)编码和封装