SpringBoot+WebSocket实现消息推送功能

目录
  • 背景
  • WebSocket简介
  • 协议原理
  • WebSocket与HTTP协议的区别
  • WebSocket特点
  • 应用场景
  • 系统集成Websocket
    • jar包引入
    • Websocket配置
    • 具体实现
    • 测试示例
    • 页面请求websocket
    • 测试效果

背景

项目中经常会用到消息推送功能,关于推送技术的实现,我们通常会联想到轮询、comet长连接技术,虽然这些技术能够实现,但是需要反复连接,对于服务资源消耗过大,随着技术的发展,HtML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。本文将介绍如何采用websocket实现消息推送。

WebSocket简介

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。浏览器和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

协议原理

Websocket协议基于Http协议,针对Http协议进行了相关的改善,且Websocket协议也需要建立TCP连接来实现数据传输,具体实现如下图:

说明:

  • 客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等。
  • 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据
  • 客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信.

WebSocket与HTTP协议的区别

相同点:都是一样基于TCP的,都是可靠性传输协议。都是应用层协议。

不同点:

  • WebSocket是双向通信协议,可以双向发送或接受信息,而HTTP是单向协议
  • WebSocket需要浏览器和服务器握手进行建立连接的,而http是浏览器发起向服务器的连接。

WebSocket特点

  • 建立在TCP协议之上,服务器端的实现比较容易。
  • 数据格式比较轻量,性能开销小,通信高效。
  • 支持多种数据格式,可以发送文本、二进制数据。
  • 客户端可以与任意服务器通信,无同源限制。

应用场景

  • 即时聊天通信
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 实时地图位置

系统集成Websocket

jar包引入

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
    <relativePath/>
 </parent>

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

Websocket配置

@Configuration
public class WebSocketConfig
{
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

具体实现

@ServerEndpoint(value="/websocket/{uid}")
@Component
public class WebSocketServer
{
    private Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    private static final AtomicInteger onlineCount = new AtomicInteger(0);

    private static CopyOnWriteArraySet<Session> sessionSet = new CopyOnWriteArraySet<Session>();

    @OnOpen
    public void onOpen(Session session,@PathParam("uid") String uid)
    {
        logger.info("open message uid:{}",uid);
        sessionSet.add(session);
        onlineCount.incrementAndGet();
        logger.info("窗口开始监听uid:{},当前在线人数:{}",uid,onlineCount);
    }

    @OnClose
    public void onClose(Session session)
    {
        String sessionId=session.getId();
        logger.info("sessionid:{} close",sessionId);
        sessionSet.remove(this);
        int count=onlineCount.decrementAndGet();
        logger.info("有一连接关闭!当前在线人数为:{}",count);
    }

    @OnError
    public void onError(Session session, Throwable error)
    {
        logger.error("消息发生错误:{},Session ID: {}",error.getMessage(),session.getId());
    }

    public void batchSendMesasge(String uid,String message) throws IOException
    {
        logger.info("推送消息到窗口:{},推送内容:{}",uid,message);
        for(Session session:sessionSet){
            sendMessage(session, message);
        }
    }

    public void sendMessage(Session session, String message) throws IOException {

        if(session!=null)
        {
            synchronized (session) {
                session.getBasicRemote().sendText(message);
            }
        }
    }

}

说明: @OnOpen :当有新的WebSocket连接进入时调用 @OnClose:当有WebSocket连接关闭时调用 @OnError :当有WebSocket抛出异常时调用 @OnMessage:当接收到字符串消息时,对该方法进行回调

测试示例

@Controller
public class WebScoketController
{
   @Autowired
   private WebSocketServer webSocketServer;

    @ResponseBody
    @RequestMapping("/sendMessage")
    public String batchMessage(String uid,String message)
    {
        Map<String, String> map =new HashMap<String, String>();
        try
        {
            map.put("code", "200");
            webSocketServer.batchSendMesasge(uid,message);
        }
        catch (Exception e)
        {
            map.put("code", "-1");
            map.put("message", e.getMessage());
        }
        return JSON.toJSONString(map);
    } 

    @GetMapping("/enter")
    public String enter()
    {
        return "webscoketTest.html";
    }
}

页面请求websocket

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>websocket test</title>

      <script type="text/javascript">
            if ("WebSocket" in window)
            {
            	console.log("您的浏览器支持 WebSocket!");

               var ws = new WebSocket("ws://127.0.0.1:9092/websocket/1234");
               console.log('ws连接状态:' + ws.readyState);

               //打开
               ws.onopen = function()
               {
                  ws.send("message test");
                  console.log("mesage sending");
               };

                //发送消息
               ws.onmessage = function (evt)
               {
                  var received_msg = evt.data;
                  alert(received_msg);
               };

                //关闭
               ws.onclose = function()
               {
                  // 关闭 websocket
                  console.log("socket is close");
               };
            }

            else
            {
            	 console.log("您的浏览器不支持 WebSocket!");
            }
      </script>
   </head>
</html>

测试效果

启动程序:运行http://localhost:9092/enter 进入页面开启websocket。

用户发送消息:http://localhost:9092/sendMessage?uid=1235&message=this%20is%20message1

执行的结果如下:

open message uid:1234
 [nio-9092-exec-2] c.s.f.w.controller.WebSocketServer: 窗口开始监听uid:1234,当前在线人数:1
 [nio-9092-exec-5] c.s.f.w.controller.WebSocketServer: 推送消息到窗口:1234,推送内容:this is message

以上就是SpringBoot+WebSocket实现消息推送功能的详细内容,更多关于SpringBoot WebSocket消息推送的资料请关注我们其它相关文章!

(0)

相关推荐

  • Springboot Websocket Stomp 消息订阅推送

    目录 需求背景 websocket协议 stomp协议 需求背景 闲话不扯,直奔主题.需要和web前端建立长链接,互相实时通讯,因此想到了websocket,后面随着需求的变更,需要用户订阅主题,实现消息的精准推送,发布订阅等,则想到了STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议. websocket协议 想到了之前写的一个websocket长链接的demo,也贴上代码供大家参考. pom文件 直接引入spring-bo

  • SpringBoot+WebSocket+Netty实现消息推送的示例代码

    上一篇文章讲了Netty的理论基础,这一篇讲一下Netty在项目中的应用场景之一:消息推送功能,可以满足给所有用户推送,也可以满足给指定某一个用户推送消息,创建的是SpringBoot项目,后台服务端使用Netty技术,前端页面使用WebSocket技术. 大概实现思路: 前端使用webSocket与服务端创建连接的时候,将用户ID传给服务端 服务端将用户ID与channel关联起来存储,同时将channel放入到channel组中 如果需要给所有用户发送消息,直接执行channel组的writ

  • 利用spring boot+WebSocket实现后台主动消息推送功能

    目录 前言: 有个需求: WebSocket 主要能实现的场景: 总结 前言: 使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!主要是tomcat的兼容与支持. 有个需求: APP用户产生某个操作,需要让后台管理系统部分人员感知(表现为一个页面消息). 最早版本是后台管理系统轮训,每隔一段时间轮训一次,由于消息重要,每隔几秒就查一次.这样做明显很不雅!会消耗大量资源,并且大部分请求是

  • 详解在Spring Boot框架下使用WebSocket实现消息推送

    spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目以及怎样为我们的Project添加HTTPS的支持,在这两篇文章的基础上,我们今天来看看如何在Spring Boot中使用WebSocket. 什么是WebSocket WebSocket为浏览器和服务器之间提供了双工异步通信功能,也就是说我们可以利用浏览器给服务器发送消息,服务器也可以给浏览器发送消息,目前主流浏览器的主流版本对WebSocket的支持都算是比较好的,但是在实际开发中使

  • Springboot+Netty+Websocket实现消息推送实例

    前言 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输. Netty框架的优势 1. API使用简单,开发门槛低:  2. 功能强大,预置了多种编解码功能,支持多种主流协议:  3. 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展:  4. 性能高,通过与其他业界主流的NIO框架对比,Netty的综

  • SpringBoot+WebSocket实现消息推送功能

    目录 背景 WebSocket简介 协议原理 WebSocket与HTTP协议的区别 WebSocket特点 应用场景 系统集成Websocket jar包引入 Websocket配置 具体实现 测试示例 页面请求websocket 测试效果 背景 项目中经常会用到消息推送功能,关于推送技术的实现,我们通常会联想到轮询.comet长连接技术,虽然这些技术能够实现,但是需要反复连接,对于服务资源消耗过大,随着技术的发展,HtML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够

  • Android中使用WebSocket实现群聊和消息推送功能(不使用WebView)

    WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex).WebSocket是Web2.0时代的新产物,用于弥补HTTP协议的某些不足,不过他们之间真实的关系是兄弟关系,都是对socket的进一步封装,其目前最直观的表现就是服务器推送和聊天功能.更多知识参考:如何理解 TCP/IP, SPDY, WebSocket 三者之间的关系? 今天的重点是讲如何在Android中脱离WebView使用WebSocket,而不是在Web浏览器

  • java WebSocket实现聊天消息推送功能

    本文实例为大家分享了java WebSocket实现聊天消息推送功能的具体代码,供大家参考,具体内容如下 环境: JDK.1.7.0_51 apache-tomcat-7.0.53 java jar包:tomcat-coyote.jar.tomcat-juli.jar.websocket-api.jar ChatAnnotation消息发送类: import java.io.IOException; import java.util.HashMap; import java.util.Map;

  • SpringMVC整合websocket实现消息推送及触发功能

    本文为大家分享了SpringMVC整合websocket实现消息推送,供大家参考,具体内容如下 1.创建websocket握手协议的后台 (1)HandShake的实现类 /** *Project Name: price *File Name: HandShake.java *Package Name: com.yun.websocket *Date: 2016年9月3日 下午4:44:27 *Copyright (c) 2016,578888218@qq.com All Rights Rese

  • Java应用层协议WebSocket实现消息推送

    目录 前言 浏览器端 服务器端 前言   大部分的web开发者,开发的业务都是基于Http协议的:前端请求后端接口,携带参数,后端执行业务代码,再返回结果给前端.作者参与开发的项目,有一个报警推送的功能,服务端实时推送报警信息给浏览器端:还有像抖音里面,如果有人关注.回复你的评论时,抖音就会推送相关消息给你了,你就会收到一条消息.   有些同学会说了,基于Http协议也能实现啊:前端定时访问后端(每隔3s或者几秒),后端返回消息数据,前端拿到后弹出消息.这种方式太low了,而且每个浏览器都这样,

  • java后端+前端使用WebSocket实现消息推送的详细流程

    目录 前言 创建WebSocket的简单实例操作流程 1.引入Websocket依赖 2.创建配置类WebSocketConfig 3.创建WebSocketServer 4.websocket调用 总结 前言 在项目的开发时,遇到实现服务器主动发送数据到前端页面的功能的需求.实现该功能不外乎使用轮询和websocket技术,但在考虑到实时性和资源损耗后,最后决定使用websocket.现在就记录一下用Java实现Websocket技术吧~ Java实现Websocket通常有两种方式:1.创建

  • php实现websocket实时消息推送

    php实现websocket实时消息推送,供大家参考,具体内容如下 SocketService.php <?php /** * Created by xwx * Date: 2017/10/18 * Time: 14:33 */ class SocketService { private $address = '0.0.0.0'; private $port = 8083; private $_sockets; public function __construct($address = '',

随机推荐