在实现消息推送的项目中往往需要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. # 2019-2020-4 《Java 程序设计》结对项目总结

    2019-2020-4 <Java 程序设计>结对项目阶段总结---<四则运算--整数> 一.需求分析 实现一个命令行程序 要求: 自动生成小学四则运算题目(加,减,乘,除): ...

  2. 2019.03.28 bzoj3325: [Scoi2013]密码(manacher+模拟)

    传送门 题意: 现在有一个nnn个小写字母组成的字符串sss. 然后给你nnn个数aia_iai​,aia_iai​表示以sis_isi​为中心的最长回文串串长. 再给你n−1n-1n−1个数bib_ ...

  3. php数组排序sort

    php的数组分为数字索引型的数组,和关键字索引的数组.如果是数字索引的,可以这样使用:$names = ['Tom', 'Rocco','amiona'];sort($names);sort()函数只 ...

  4. s6-5 TCP 连接的建立

    TCP 连接的建立 采用三次握手建立连接 一方(server)被动地等待一个进来的连接请求 另一方(the client)通过发送连接请求,设置一些参数 服务器方回发确认应答 应答到达请求方,请求方最 ...

  5. 【深度学习】安装TensorFlow-GPU

    1.Windows版 准备 干净的系统,没有安装过Python,有的话就卸载了. 另外我的系统安装了VS2015 VS2017(这里我不知道是不是必备的). 现在TensorFlow和cuda以及cu ...

  6. lwip协议栈学习---udp

    书籍:<嵌入式网络那些事-lwip协议> udp协议的优点: 1)基于IP协议,无连接的用户数据报协议,适用于传送大批量数据, 2)实时性比较高,适用于嵌入式网络 发送函数:udp_sen ...

  7. Windows多线程学习随笔

    自学Windows多线程知识,例程如下: #include <iostream> #include <windows.h> #include <process.h> ...

  8. 算法学习笔记:knn理论介绍

    阅读对象:了解指示函数,了解训练集.测试集的概念. 1.简介 knn算法是监督学习中分类方法的一种.所谓监督学习与非监督学习,是指训练数据是否有标注类别,若有则为监督学习,若否则为非监督学习.所谓K近 ...

  9. [转]Java工程师技术栈--成神之路

    一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133http://if ...

  10. python_flask 基础巩固 (URL传输传递方式)

    URL传输传递@app.route('/'):@app.route('/list/')@app.route('/list/<int:id>/')@app.route('/list/< ...