在实现消息推送的项目中往往需要WebSocket,以下简单讲解在Spring boot 中使用 WebSocket。

1、pom.xml 中引入 spring-boot-starter-websocket

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

2、往spring容器中注入 ServerEndpointExporter

package com.sam.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter; /**
* WebSocket配置
* <p>
* 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
* 要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
*
* @author sam
* @since 2017/9/13
*/ @Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
} }

3、Endpoint 具体实现

package com.sam.websocket;

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.Map;
import java.util.concurrent.ConcurrentHashMap; /**
* ServerEndpoint
* <p>
* 使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。
* <p>
* 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
*
* @author sam
* @since 2017/9/13
*/
@ServerEndpoint("/ws/chatRoom/{userName}") //WebSocket客户端建立连接的地址
@Component
public class ChatRoomServerEndpoint { /**
* 存活的session集合(使用线程安全的map保存)
*/
private static Map<String, Session> livingSessions = new ConcurrentHashMap<>(); /**
* 建立连接的回调方法
*
* @param session 与客户端的WebSocket连接会话
* @param userName 用户名,WebSocket支持路径参数
*/
@OnOpen
public void onOpen(Session session, @PathParam("userName") String userName) {
livingSessions.put(session.getId(), session);
sendMessageToAll(userName + " 加入聊天室");
} /**
* 收到客户端消息的回调方法
*
* @param message 客户端传过来的消息
* @param session 对应的session
*/
@OnMessage
public void onMessage(String message, Session session, @PathParam("userName") String userName) {
sendMessageToAll(userName + " : " + message);
} /**
* 发生错误的回调方法
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
} /**
* 关闭连接的回调方法
*/
@OnClose
public void onClose(Session session, @PathParam("userName") String userName) {
livingSessions.remove(session.getId());
sendMessageToAll(userName + " 退出聊天室");
} /**
* 单独发送消息
*
* @param session
* @param message
*/
public void sendMessage(Session session, String message) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 群发消息
*
* @param message
*/
public void sendMessageToAll(String message) {
livingSessions.forEach((sessionId, session) -> {
sendMessage(session, message);
});
} }

4、前端页面实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>聊天室</title>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
</head>
<body>
<h1>聊天室</h1> <textarea id="chat_content" readonly="readonly" cols="100" rows="9"> </textarea> <br> 用户:<input type="text" id="user_name" value="" name="userName"/>
<button id="btn_join">加入聊天室</button>
<button id="btn_exit">退出聊天室</button> <br> 消息:<input type="text" id="send_text" value="" name="sendText"/>
<button id="btn_send">发送</button> </body>
</html> <script>
$(function () { var prefixUrl = 'ws://127.0.0.1:8080/ws/chatRoom/'; var ws;//WebSocket连接对象 //判断当前浏览器是否支持WebSocket
if (!('WebSocket' in window)) {
alert('Not support websocket');
} $('#btn_join').click(function () { var userName = $('#user_name').val(); //创建WebSocket连接对象
ws = new WebSocket(prefixUrl + userName); //连接成功建立的回调方法
ws.onopen = function (event) {
console.log('建立连接')
} //接收到消息的回调方法
ws.onmessage = function (event) {
console.log('接收到内容:' + event.data)
$('#chat_content').append(event.data + '\n')
} //连接发生错误的回调方法
ws.onerror = function (event) {
console.log('发生错误')
} //连接关闭的回调方法
ws.onclose = function (event) {
console.log('关闭连接')
} }) //发送消息
function sendMessage(message) {
ws.send(message);
} //关闭连接
function closeWebSocket() {
ws.close();
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
wx.close();
} //发送消息
$('#btn_send').click(function () {
sendMessage($('#send_text').val())
}) //点击退出聊天室
$('#btn_exit').click(function () {
closeWebSocket();
})
})
</script>

以上为完整demo内容。

推荐: 阿里技术-小马哥讲解WebSocket

Spring Boot 系列 - WebSocket 简单使用的更多相关文章

  1. 【websocket】spring boot 集成 websocket 的四种方式

    集成 websocket 的四种方案 1. 原生注解 pom.xml <dependency> <groupId>org.springframework.boot</gr ...

  2. 国内最全的Spring Boot系列之二

    历史文章 <国内最全的Spring Boot系列之一> 视频&交流平台 SpringBoot视频:http://t.cn/R3QepWG Spring Cloud视频:http:/ ...

  3. Spring Boot 系列教程19-后台验证-Hibernate Validation

    后台验证 开发项目过程中,后台在很多地方需要进行校验操作,比如:前台表单提交,调用系统接口,数据传输等.而现在多数项目都采用MVC分层式设计,每层都需要进行相应地校验. 针对这个问题, JCP 出台一 ...

  4. Spring Boot 系列教程18-itext导出pdf下载

    Java操作pdf框架 iText是一个能够快速产生PDF文件的java类库.iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的.它的类库尤其与java Servlet有很好 ...

  5. Spring Boot 系列教程15-页面国际化

    internationalization(i18n) 国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式. 它要求从产品中抽离所有地域语言,国家/地区和 ...

  6. Spring Boot 系列教程12-EasyPoi导出Excel下载

    Java操作excel框架 Java Excel俗称jxl,可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件,现在基本没有更新了 http://jxl.sourcef ...

  7. Spring Boot 系列教程11-html页面解析-jsoup

    需求 需要对一个页面进行数据抓取,并导出doc文档 html解析器 jsoup 可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操 ...

  8. Spring Boot 系列教程10-freemarker导出word下载

    freemarker FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用户的,而是一个 ...

  9. Spring Boot 系列教程9-swagger-前后端分离后的标准

    前后端分离的必要 现在的趋势发展,需要把前后端开发和部署做到真正的分离 做前端的谁也不想用Maven或者Gradle作为构建工具 做后端的谁也不想要用Grunt或者Gulp作为构建工具 前后端需要通过 ...

随机推荐

  1. 洛谷[LnOI2019]长脖子鹿省选模拟赛 简要题解

    传送门 听说比赛的时候T4T4T4标程锅了??? WTF换我时间我要写T3啊 于是在T4T4T4调半天无果的情况下260pts260pts260pts收场真的是tcltcltcl. T1 快速多项式变 ...

  2. unittest_API自动化脚本应用

    import urllib.request import urllib.parse import json import unittest from HTMLTestRunner import HTM ...

  3. linux 挂载ntfs格式的硬盘

    一.安装ntfs 1.下载 sudo wget  https://tuxera.com/opensource/ntfs-3g_ntfsprogs-2017.3.23.tgz 2.解压 sudo tar ...

  4. 1030 Travel Plan Dijkstra+dfs

    和1018思路如出一辙,先求最短路径,再dfs遍历 #include <iostream> #include <cstdio> #include <vector> ...

  5. npm Error: Cannot find module './auth.js'

    Mac 下升级 npm 到 v6.8.0 翻车. 提示: Error: Cannot find module './auth.js' 根据回显的报错路径,定位到这个文件中: npm/node_modu ...

  6. 日期类时间类,日期时间类,单例模式,装箱与拆箱,数字类随机数,BigDecimal总结

    1.日期类,时间类,日期时间类 初步日期使用方法及格式转换方法(旧方法): 格式://Mon Jul 30 11:26:05 CST 2018             年月日时分秒    CST代表北 ...

  7. android 图片内存管理

    图片对象: drawable bitmap etc.图片对象在Android上该缓存吗?什么时候缓存?怎么缓存?缓存后使用时怎么取出?怎么销毁?什么时候销毁? bitmap对象(new出来的) :需要 ...

  8. Activity的task任务栈

    转自http://blog.csdn.net/liuhe688/article/details/6761337 古人學問無遺力,少壯工夫老始成.紙上得來終覺淺,絕知此事要躬行.南宋.陸遊<冬夜讀 ...

  9. LVS简单介绍

    一.LVS简介 linux virtual server简称LVS,Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器 ...

  10. 每天学点SpringCloud(十):SpringCloud监控

    今天我们来学习一下actuator这个组件,它不是SpringCloud之后才有的,而是SpringBoot的一个starter,Spring Boot Actuator.我们使用SpringClou ...