SpringBoot+WebSocket搭建简单的多人聊天系统

前言

今天闲来无事,就来了解一下WebSocket协议。来简单了解一下吧。

WebSocket是什么

首先了解一下WebSocket是什么?WebSocket是一种在单个TCP连接上进行全双工通信的协议。这是一种比较官方的说法,简单点来说就是,在一次TCP连接中,通信的双方可以相互通信。比如A和B在打电话,A说话的时候,B也可以说话来进行信息的交互,这就叫做全双工通信。对应的是单工通信,和半双工通信,单工通信就是只能由A向B通信,比如电脑和打印机。半双工通信是可以AB可以互相通信,但是同一时间只能进行单向通信,比如对讲机。

WebSocket与http有啥区别

相同点

都建立在TCP之上,通过TCP协议来传输数据。

不同点

HTTP协议为单向协议,即浏览器只能向服务器请求资源,服务器才能将数据传送给浏览器,而服务器不能主动向浏览器传递数据。分为长连接和短连接,短连接是每次http请求时都需要三次握手才能发送自己的请求,每个request对应一个response;长连接是短时间内保持连接,保持TCP不断开,指的是TCP连接。

WebSocket一种双向通信协议,在建立连接后,WebSocket服务器和客户端都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。WebSocket在建立握手连接时,数据是通过http协议传输的,“GET/chat HTTP/1.1”,这里面用到的只是http协议一些简单的字段。但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

用处

WebSocket解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮询问题。

使用WebSocket搭建一个多人聊天系统

引入WebSocket的jar包

Gradle:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.1.8.RELEASE'

Maven:

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

添加对WebSocket的支持

注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
 * @author: zp
 * @Date: 2019-09-18 10:03
 * @Description:
 */
@Configuration
public class AppConfiguration {
 @Bean
 public ServerEndpointExporter serverEndpointExporter(){
  return new ServerEndpointExporter();
 }
}

创建WebSocket的实现类

@ServerEndpoint("/webSocket/{page}")中的值就是需要访问的地址,和Controller中的@RequestMapping有点类似。然后实现@OnOpen(打开连接),@OnClose(关闭连接),@onMessage(收到消息),@Error(触发异常)。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * @author: zp
 * @Date: 2019-09-20 15:12
 * @Description:
 */
@Component
@ServerEndpoint("/webSocket/{page}")
public class WebSocket {
 private Logger log = LoggerFactory.getLogger(this.getClass());
 /**
  * 用来记录房间的人数
  */
 private static AtomicInteger onlinePersons = new AtomicInteger(0);
 /**
  * 用来记录房间及人数
  */
 private static Map<String,Set> roomMap = new ConcurrentHashMap(8);
 @OnOpen
 public void open(@PathParam("page") String page, Session session) throws IOException {
  Set set = roomMap.get(page);
  // 如果是新的房间,则创建一个映射,如果房间已存在,则把用户放进去
  if(set == null){
   set = new CopyOnWriteArraySet();
   set.add(session);
   roomMap.put(page,set);
  }else{
   set.add(session);
  }
  // 房间人数+1
  onlinePersons.incrementAndGet();
  log.info("新用户{}进入聊天,房间人数:{}",session.getId(),onlinePersons);
 }
 @OnClose
 public void close(@PathParam("page") String page, Session session){
  // 如果某个用户离开了,就移除相应的信息
  if(roomMap.containsKey(page)){
   roomMap.get(page).remove(session);
  }
  // 房间人数-1
  onlinePersons.decrementAndGet();
  log.info("用户{}退出聊天,房间人数:{}",session.getId(),onlinePersons);
 }
 @OnMessage
 public void reveiveMessage(@PathParam("page") String page, Session session,String message) throws IOException {
  log.info("接受到用户{}的数据:{}",session.getId(),message);
  // 拼接一下用户信息
  String msg = session.getId()+" : "+ message;
  Set<Session> sessions = roomMap.get(page);
  // 给房间内所有用户推送信息
  for(Session s : sessions){
   s.getBasicRemote().sendText(msg);
  }
 }
 @OnError
 public void error(Throwable throwable){
  try {
   throw throwable;
  } catch (Throwable e) {
   log.error("未知错误");
  }
 }
}

写个超级简单的页面测试一下

前端有点菜,写不出好看的ui,见谅~

<html>
<head>
 <meta charset="UTF-8"></meta>
 <title>springboot项目WebSocket测试demo</title>
</head>
<body>
<h3>springboot项目websocket测试demo</h3>
<h4>测试说明</h4>
<h5>文本框中数据数据,点击‘发送测试',文本框中的数据会发送到后台websocket,后台接受到之后,会再推送数据到前端,展示在下方;点击关闭连接,可以关闭该websocket;可以跟踪代码,了解具体的流程;代码上有详细注解</h5>
<br />
<input id="text" type="text" />
<button onclick="send()">发送测试</button>
<hr />
<button onclick="clos()">关闭连接</button>
<hr />
<div id="message"></div>
<script>
 var websocket = null;
 if('WebSocket' in window){
  websocket = new WebSocket("ws://127.0.0.1:9999/webSocket/1");
 }else{
  alert("您的浏览器不支持websocket");
 }
 websocket.onerror = function(){
  setMessageInHtml("send error!");
 }
 websocket.onopen = function(){
  setMessageInHtml("连接成功!")
  setTimeout(function(){setMessageInHtml("欢迎来到这里!")
 },2000)
 }
 websocket.onmessage = e => setMessageInHtml(e.data)
 websocket.onclose = function(){
  setMessageInHtml("连接断开!")
 }
 window.onbeforeunload = function(){
  clos();
 }
 function setMessageInHtml(message){
  document.getElementById('message').innerHTML += message+"</br>";
 }
 function clos(){
  websocket.close(3000,"强制关闭");
 }
 function send(){
  var msg = document.getElementById('text').value;
  websocket.send(msg);
 }
</script>
</body>
</html>

测试

总结

以上所述是小编给大家介绍的SpringBoot+WebSocket搭建简单的多人聊天系统,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • SpringBoot跨系统单点登陆的实现方法

    什么是单点登陆 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性.当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录.这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中.相同的,单一退出(single sign-off)就是指,只需要单一的退出动作,就可以结束对于多个系统的访问权限. 单点登陆带来的好处 降低访问

  • spring boot+thymeleaf+bootstrap实现后台管理系统界面

    最近在学spring boot ,学习一个框架无非也就是使用它来做以前做的事情,两者比较才有不同,说一下自己使用的体会. 先来说下spring boot ,微框架.快速开发,相当于零配置,从一个大神那看来的说:spring boot 相当于框架的框架 ,就是集成了很多,用哪个添加哪个的依赖就行,这样的话自己看不到配置,对于习惯了使用配置刚使用spring boot的开发者来说可能还有点不习惯,什么都不用配,看不到配置感觉对项目整体架构有点陌生,再说在spring boot 中使用 thymele

  • 如何通过SpringBoot实现商城秒杀系统

    这篇文章主要介绍了如何通过SpringBoot实现商城秒杀系统,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 学习自:地址 1.主要流程 1.1数据库: 1.2 环境 window下:Zookeeper,Redis,rabbitmq-server.jdk1.8以上. 1.3 介绍 这里只做秒杀部分功能,其他功能不会涉及.项目运行后可访问秒杀商品页面 当用户没登陆,点击详情会跳转到登陆页面. 用户登陆后可以查看商品的详情并进行抢购. 注意,用户对

  • 详解在spring boot中消息推送系统设计与实现

    推送系统作为通用的组件,存在的价值主要有以下几点 会被多个业务项目使用,推送系统独立维护可降低维护成本 推送系统一般都是调用三方api进行推送,三方api一般会有调用频率/次数限制,被推送的消息需要走队列来合理调用三方api,控制调用的频率和次数 业务无关,一般推送系统设计成不需要关心业务逻辑 核心技术 消息队列 三方服务api调用 安卓app推送 苹果app推送 微信小程序推送 邮件推送 钉钉推送 短信推送 消息队列选用阿里云提供的rocketmq,官方文档:https://help.aliy

  • Spring Boot 开发私有即时通信系统(WebSocket)

    1/ 概述 利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天. 2/ 所需依赖 Spring Boot 版本 1.5.3,使用MongoDB存储数据(非必须),Maven依赖如下: <properties> <java.version>1.8</java.version> <thymeleaf.version>3.0.0.RELEASE</thymeleaf.ve

  • Spring Boot 会员管理系统之处理文件上传功能

    温馨提示 Spring Boot会员管理系统的中,需要涉及到Spring框架,SpringMVC框架,Hibernate框架,thymeleaf模板引擎.所以,可以学习下这些知识.当然,直接入门的话使用是没问题,但是,涉及到一些异常和原理的话可能就有些困难. 1. 前端部分 在前端部分addMember.html是通过form表单来提交会员的信息,其中就包括了图片上传功能(这里涉及了文件上传操作),表单部分代码如下: <form th:action="@{/admin/addMember}

  • 基于springboot搭建的web系统架构的方法步骤

    从接触springboot开始,便深深的被它的简洁性深深的折服了,精简的配置,方便的集成,使我再也不想用传统的ssm框架来搭建项目,一大堆的配置文件,维护起来很不方便,集成的时候也要费力不少.从第一次使用springboot开始,一个简单的main方法,甚至一个配置文件也不需要(当然我是指的没有任何数据交互,没有任何组件集成的情况),就可以把一个web项目启动起来,下面总结一下自从使用springboot依赖,慢慢完善的自己的一个web系统的架构,肯定不是最好的,但平时自己用着很舒服. 1. 配

  • Spring Boot与Spark、Cassandra系统集成开发示例

    本文演示以Spark作为分析引擎,Cassandra作为数据存储,而使用Spring Boot来开发驱动程序的示例. 1.前置条件 安装Spark(本文使用Spark-1.5.1,如安装目录为/opt/spark) 安装Cassandra(3.0+) 创建keyspace CREATE KEYSPACE hfcb WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 3 }; 创建table CREATE

  • Spring Boot中使用 Spring Security 构建权限系统的示例代码

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 权限控制是非常常见的功能,在各种后台管理里权限控制更是重中之重.在Spring Boot中使用 Spring Security 构建权限系统是非常轻松和简单的.下面我们就来快速入门 Spring Security .在开始前我们需要一对

  • SpringBoot+WebSocket搭建简单的多人聊天系统

    前言 今天闲来无事,就来了解一下WebSocket协议.来简单了解一下吧. WebSocket是什么 首先了解一下WebSocket是什么?WebSocket是一种在单个TCP连接上进行全双工通信的协议.这是一种比较官方的说法,简单点来说就是,在一次TCP连接中,通信的双方可以相互通信.比如A和B在打电话,A说话的时候,B也可以说话来进行信息的交互,这就叫做全双工通信.对应的是单工通信,和半双工通信,单工通信就是只能由A向B通信,比如电脑和打印机.半双工通信是可以AB可以互相通信,但是同一时间只

  • SpringBoot+Websocket实现一个简单的网页聊天功能代码

    最近做了一个SpringBoot的项目,被SpringBoot那简介的配置所迷住.刚好项目中,用到了websocket.于是,我就想着,做一个SpringBoot+websocket简单的网页聊天Demo. 效果展示: 当然,项目很简单,没什么代码,一眼就能明白 导入websocket的包. 通过使用SpringBoot导入包的时候,我们可以发现,很多包都是以 spring-boot-starter 开头的,对于我这种强迫症 ,简直是福音 <dependency> <groupId>

  • springboot+websocket+redis搭建的实现

    在多负载环境下使用websocket. 一.原因 在某些业务场景,我们需要页面对于后台的操作进行实时的刷新,这时候就需要使用websocket. 通常在后台单机的情况下没有任何的问题,如果后台经过nginx等进行负载的话,则会导致前台不能准备的接收到后台给与的响应.socket属于长连接,其session只会保存在一台服务器上,其他负载及其不会持有这个session,此时,我们需要使用redis的发布订阅来实现,session的共享. 二.环境准备 在https://mvnrepository.

  • SpringBoot+WebSocket实现多人在线聊天案例实例

    目录 1.pom.xml 2.消息实体类 3.controller 4.WebSocket的配置文件 5.前端发送消息页面 6.测试 6.1.客户端A 6.2.客户端B 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o

  • SpringBoot webSocket实现发送广播、点对点消息和Android接收

    1.SpringBoot webSocket SpringBoot 使用的websocket 协议,不是标准的websocket协议,使用的是名称叫做STOMP的协议. 1.1 STOMP协议说明 STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议. 它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消

  • 解决SpringBoot webSocket 资源无法加载、tomcat启动报错的问题

    问题描述: 1. 项目集成WebSocket,且打包发布tomcat时出现websocket is already in CLOSING or CLOSE state这样的问题,建议参考"解决方法二",但是"解决方法一"请要了解查看 ,因为解决方法二是在一的基础上进行更正 2. 如果出现javax.websocket.server.ServerContainer not available这样的错误,请参考"解决方法一"中步骤3 解决方法一:(常

  • Java实战之用springboot+netty实现简单的一对一聊天

    一.引入pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4

  • php基于websocket搭建简易聊天室实践

    本文实例讲述了php基于websocket搭建简易聊天室实践.分享给大家供大家参考.具体如下: 1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短连接和长连接.短连接一般可以用ajax实现,长连接就是websocket.短连接实现起来比较简单,但是太过于消耗资源.websocket高效不过兼容存在点问题.websocket是html5的资源 2.前

  • 详解mall整合SpringBoot+MyBatis搭建基本骨架

    SpringBoot实战电商项目mall(20k+star)地址:https://github.com/macrozheng/mall 摘要 本文主要讲解mall整合SpringBoot+MyBatis搭建基本骨架,以商品品牌为例实现基本的CRUD操作及通过PageHelper实现分页查询. mysql数据库环境搭建 下载并安装mysql5.7版本,下载地址:https://dev.mysql.com/downloads/installer/ 设置数据库帐号密码:root root 下载并安装客

  • SpringBoot环境搭建及第一个程序运行(小白教程)

    spring boot简介 spring boot框架抛弃了繁琐的xml配置过程,采用大量的默认配置简化我们的开发过程. 所以采用Spring boot可以非常容易和快速地创建基于Spring 框架的应用程序,它让编码变简单了,配置变简单了,部署变简单了,监控变简单了. 说的直白一些使用spring boot之后就不用像以前使用ssm的时候添加那么多配置文件了,spring boot除了支持ssm之外,还支持非常多的第三方技术.spring boot就像是一个百宝箱,你要用那些技术,直接告诉他就

随机推荐