Spring Boot 为 websocket 提供了一些默认配置,简化了 websocket 使用,这里我们将使用 Spring Boot websocket,并加入 stomp 和 sockjs 的支持,快速编写一个简单的网页聊天室,实现广播消息推送以及点对点的私人消息推送。

篇幅限制下边只给出关键的代码,需要 HTML 页面代码或项目完整源代码的可到这里查看(使用 IDEA 导入后可直接运行)。

基本页面:

将服务器关闭,客户端自动重连:

超过重连次数后,不再重连:

项目的编写分为服务器端和客户端,因此下边也就分为这两个方面进行讲述

服务端

由于 spring boot 的默认配置,大大简化了开发,服务器端需要编写的只有两个地方:配置类和控制器。

当然首先需要引入依赖(这里使用 gradle 作为包管理工具)

compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-websocket')

编写配置类

然后是 websocket 的配置类 WebSocketConfig,配置项的解释见注释

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {registry.enableSimpleBroker("/topic", "/user");// “/topic“ 用于给客户端订阅广播信息,”/user“用于给客户端订阅点对点消息//registry.setApplicationDestinationPrefixes("/app");// 客户端向服务器发送消息时 URL 为:【/app + controller中 @MessageMapping 的地址】,此处暂时不使用该配置//registry.setUserDestinationPrefix("/user/");// 客户端向指定用户发送(一对一)信息时 URL 前缀是“/user/”,即使不配置默认也是“/user/“}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/endpoint").withSockJS();//注册客户端websocket连接的端口}
}

编写 controller

@Controller
public class WebsocketController {/*** 广播推送* @param text* @param sessionId* @return* @throws Exception*/@MessageMapping(value = "/chat")@SendTo("/topic/getResponse")public String talk(@Payload String text, @Header("simpSessionId") String sessionId) throws Exception {return "【" + sessionId + "】说:【" + text + "】";}/*** 点对点推送* @param text* @param sessionId* @return* @throws Exception*/@MessageMapping(value = "/speak")@SendToUser(value = "/personal")public String speak(@Payload String text, @Header("simpSessionId") String sessionId) throws Exception {return text;}/*** 异常信息推送* @param exception* @return*/@MessageExceptionHandler@SendToUser(value = "/errors")public String handleException(Throwable exception) {return exception.getMessage();}
}

这里需要说一下其中用到的几个注解:
- 方法注解
- @MessageMapping(value = “/URL”) 匹配客户端 send 消息时的URL;
- @sendTo 和 @sendToUser 分别用于给客户端订阅广播消息和点对点消息;
- 参数注解
- @Payload:使用客户端 STOMP 帧的 body 赋值;
- @Header(“xxx”):使用客户端 STOMP 帧的 headers 中的 xxx 赋值;

在查阅资料的时候,看到也可以使用 SimpMessagingTemplate 进行消息的代理转发,可以这么理解:

@MessageMapping("/chat")
public void chat(String value){this.simpMessagingTemplate.convertAndSend("/topic/getResponse", value);
}

等同于

@MessageMapping("/chat")
@SendTo("/topic/getResponse")
public String chat(String value) {return value;
}

客户端

客户端的代码主要是使用 JavaScript 进行 websocket 的一系列操作,由于使用 STOMP 协议,因此需要使用 STOMP API, 关于 STOMP API 的使用,可以参考这里的 总结。

基本操作如下

var socket = new SockJS('/endpoint');
stompClient = Stomp.over(socket);
stompClient.connect({}, function connectCallback (frame) {...}, function errorCallBack (error) {...}
);

一对一消息推送

// 获取 socket 连接的sessionId,即从 socket._transport.url 中使用正则截取
var sessionId = /\/([^\/]+)\/websocket/.exec(socket._transport.url)[1];
console.log("connected, session id: " + sessionId);
......
// 订阅私人消息
var subscription_personal = stompClient.subscribe('/user/' + sessionId + '/personal', function callBack (response) {if (response.body) {printToScreen("【私人消息】" + response.body);} else {printToScreen("收到一个空消息");}
}
......
// 发送消息
stompClient.send("/speak", headers, JSON.stringify(body));

广播消息推送

......
// 订阅广播消息
var subscription_broadcast = stompClient.subscribe('/topic/getResponse', function callBack (response) {if (response.body) {printToScreen("【广播】" + response.body);} else {printToScreen("收到一个空消息");}
});
......
// 发送广播消息
stompClient.send("/chat", headers, JSON.stringify(body));

异常消息推送

// 获取 websocket 连接的 sessionId
var sessionId = /\/([^\/]+)\/websocket/.exec(socket._transport.url)[1];
// 订阅异常消息
var subscription_errors = stompClient.subscribe('/user/' + sessionId + '/errors', function callBack (response) {if (response.body) {printToScreen("【异常消息】" + response.body);} else {printToScreen("收到一个空消息");}
});

自动重连机制

使用JavaScript设置自动重连机制,与服务器断开连接后自动重来,重连失败超过10后不再重连

function errorCallBack (error) {document.getElementById("state-info").innerHTML = "连接断开";console.log('连接断开【' + error + '】');if (curTryNum <= maxTryNum) {document.getElementById("state-info").innerHTML = "连接关闭,10秒后重新连接……";console.log("连接关闭,10秒后重新连接……");// 10秒后重新连接,实际效果:每10秒重连一次,直到连接成功setTimeout(function () {connect();}, 10000);} else {document.getElementById("state-info").innerHTML = "连接关闭,且已超过最大重连次数,不再重连";console.log("连接关闭,且已超过最大重连次数,不再重连");}
}

使用 Spring Boot websocket 写简单网页聊天室相关推荐

  1. SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室

    SpringBoot入门建站全系列(二十七)WebSocket做简单的聊天室 一.概述 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 ...

  2. 原生php写简单的聊天室

    Websocket.php <?php $ws_server = new swoole_websocket_server('此处是你的域名/ip',端口号); //设置server运行时的参数 ...

  3. Java和WebSocket开发网页聊天室

    一.项目简介 WebSocket是HTML5一种新的协议,它实现了浏览器与服务器全双工通信,这里就将使用WebSocket来开发网页聊天室,前端框架会使用AmazeUI,后台使用Java,编辑器使用U ...

  4. 基于WebSocket实现网页聊天室

    背景 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 ...

  5. java web 聊天室_Java和WebSocket开发网页聊天室

    小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ 一.项目简介WebSocket是HTML5一种新的 ...

  6. springboot 使用 Spring Boot WebSocket 创建聊天室 2-11

    什么是 WebSocket WebSocket 协议是基于 TCP 的一种网络协议,它实现了浏览器与服务器全双工(Full-duplex)通信-允许服务器主动发送信息给客户端. 以前,很多网站为了实现 ...

  7. Spring Boot WebChat 网页聊天室

    使用Spring Boot +Spring Security+Spring Data Jpa+Thymeleaf+Spring websocket 搭建的简易网页聊天室. 项目源码参考:http:// ...

  8. 使用spring boot +WebSocket实现(后台主动)消息推送

    前言:使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!使用此webscoket务必确保生产环境能兼容/支持!主要是tomcat的兼容与支持. ...

  9. 【系统开发】WebSocket + SpringBoot + Vue 搭建简易网页聊天室

    文章目录 一.数据库搭建 二.后端搭建 2.1 引入关键依赖 2.2 WebSocket配置类 2.3 配置跨域 2.4 发送消息的控制类 2.5 R类 三.前端搭建 3.1 自定义文件websock ...

  10. WebSocket 网页聊天室的实现(服务器端:.net + windows服务,前端:Html5)

    websocket是HTML5中的比较有特色一块,它使得以往在客户端软件中常用的socket在web程序中也能轻松的使用,较大的提高了效率.废话不多说,直接进入题. 网页聊天室包括2个部分,后端服务器 ...

最新文章

  1. 北大校友“炼丹”分享:OpenAI如何训练千亿级模型?
  2. php常见的类库-文件操作类
  3. System.out.println(Runtime.getRuntime().availableProcessors());获取cpu核数
  4. forEach和for in
  5. 如何清除html代码里的空格,如何从html源代码中删除空格
  6. 良好的编码风格 java_关于java:编码风格是否遵循良好做法
  7. 华为Mate40 RS保时捷设计推8+256GB版本:起售价便宜1000元
  8. 怎么把做好的ps保存成图片_ps存成jpg格式的快捷键,ps如何另存为图片格式
  9. 最新架构amd服务器cpu,2015年或新变化?AMD将专注高性能架构
  10. 思科服务器怎么看主板型号,原装思科CISCO模块VWIC-2MFT-G703
  11. Deepin下安装日文输入法
  12. 汉字转语音 android 软件,文字转语音助手
  13. 帝国cms如何给网站添加百度统计代码,百度统计安装教程步骤分享
  14. Chuck语言学习笔记——2.HelloWorld
  15. 电商平台二清该怎样合规?
  16. 【微信小程序】Java岗面试12家大厂成功跳槽
  17. solr mysql增量导入_10.Solr4.10.3数据导入(DIH全量增量同步Mysql数据)
  18. MOSFET的误启动发生机制-3
  19. 岚图汽车中大型智能电动SUV完成高温高原严苛测试
  20. 集抄终端测试软件,远程抄表集抄系统

热门文章

  1. [翻译]X窗口管理器的原理剖析(一)
  2. html js设置旋转动画效果图,原生JS实现逼真的图片3D旋转效果详解
  3. 计算机无法备份,无法备份和备份会话失败iTunes问题解决
  4. 【CityHunter】服务器端设计思路
  5. ASP.NET 安全认证(三)
  6. 【玩转微信公众平台之中的一个】序章(纯粹扯淡)
  7. VUE+Element学习笔记之登录页面跳转首页
  8. 在火狐浏览器中获得borderColor的值
  9. 斯蒂文斯理工学院计算机专业,斯蒂文斯理工学院计算机专业
  10. win10系统怎么打开pdf文件