webSocket入门小案例(搭建实时交互的群聊+点对点的交流)

2023-12-31 22:58

本文主要是介绍webSocket入门小案例(搭建实时交互的群聊+点对点的交流),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、简介

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、添加依赖

        <!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!--前端框架sockjs-client--><dependency><groupId>org.webjars</groupId><artifactId>sockjs-client</artifactId><version>1.1.2</version></dependency><!--前端框架jquery--><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.4.1</version></dependency><!--前端框架stomp-websocket--><dependency><groupId>org.webjars</groupId><artifactId>stomp-websocket</artifactId><version>2.3.3</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>webjars-locator-core</artifactId></dependency><!--点对点通信需要用到的依赖 主要是为了获取安全登录的用户信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

三、创建websocketConfig文件 

@Configuration
@EnableWebSocketMessageBroker //启动websocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Override public void configureMessageBroker(MessageBrokerRegistry registry) {//注册代理对象 /topic 用于群聊广播 ; /user 用于点对点用户通信registry.enableSimpleBroker("/topic","/user"); //全局客户端使用的前缀registry.setApplicationDestinationPrefixes("/app");//点对点使用的前缀 无需配置 默认/user//registry.setUserDestinationPrefix("/user");}//注册stomp端点@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {//允许使用socketJs方式访问 即可通过http://IP:PORT/chat来和服务端websocket连接registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();}
}

 配置SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@BeanPasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("java").password("123").roles("admin").and().withUser("four").password("123").roles("user");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().permitAll();}
}

 

三、创建接受数据的实体类

 Message:群聊中消息的封装;广播的内容为什么用户发送了什么内容

public class Message {private String name;private String content;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}

 Chat:点对点用户的通信

public class Chat {private String from; //发送消息的用户private String content; //消息的内容private String to; // 接收消息的用户public String getFrom() {return from;}public void setFrom(String from) {this.from = from;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getTo() {return to;}public void setTo(String to) {this.to = to;}
}

四、controller

简单说一下Principal principal这个类  在spring security 的环境下登录后 用户的认证信息会由框架自动封装在Principal中

@Controller
public class GreetingController {@AutowiredSimpMessagingTemplate simpMessagingTemplate;
//    @MessageMapping("/hello")
//    @SendTo("/topic/greetings")
//    public Message greeting(Message message) {
//        return message;
//    }//群聊广播的接口@MessageMapping("/hello")public void greeting(Message message) {simpMessagingTemplate.convertAndSend("/topic/greetings", message);}//单聊的接口@MessageMapping("/chat")public void chat(Principal principal, Chat chat) {chat.setFrom(principal.getName());simpMessagingTemplate.convertAndSendToUser(chat.getTo(), "/user/chat", chat);}
}

五、前端简易页面实现

群聊:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>群聊</title><!--前端框架 --><script src="/webjars/jquery/jquery.min.js"></script><script src="/webjars/sockjs-client/sockjs.min.js"></script><script src="/webjars/stomp-websocket/stomp.min.js"></script>
</head>
<body><table><tr><td>请输入用户名</td><td><input type="text" id="name"></td></tr><tr><td><input type="button" id="connect" value="连接"></td><td><input type="button" id="disconnect" disabled="disabled" value="断开连接"></td></tr>
</table>
<div id="chat" style="display: none"><table><tr><td>请输入聊天内容</td><td><input type="text" id="content"></td><td><input type="button" id="send" value="发送"></td></tr></table><div id="conversation">群聊进行中...</div>
</div>
<script>$(function () {$("#connect").click(function () {connect();})$("#disconnect").click(function () {if (stompClient != null) {stompClient.disconnect();}setConnected(false);})$("#send").click(function () {stompClient.send('/app/hello',{},JSON.stringify({'name':$("#name").val(),'content':$("#content").val()}))})})var stompClient = null;function connect() {if (!$("#name").val()) {return;}var socket = new SockJS('/chat');stompClient = Stomp.over(socket);stompClient.connect({}, function (success) {setConnected(true);stompClient.subscribe('/topic/greetings', function (msg) {showGreeting(JSON.parse(msg.body));});})}function showGreeting(msg) {$("#conversation").append('<div>' + msg.name + ':' + msg.content + '</div>');}function setConnected(flag) {$("#connect").prop("disabled", flag);$("#disconnect").prop("disabled", !flag);if (flag) {$("#chat").show();} else {$("#chat").hide();}}
</script>
</body>
</html>

单聊:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>单聊</title><script src="/webjars/jquery/jquery.min.js"></script><script src="/webjars/sockjs-client/sockjs.min.js"></script><script src="/webjars/stomp-websocket/stomp.min.js"></script>
</head>
<body>
<input type="button" id="connect" value="连接">
<input type="button" id="disconnect" disabled="disabled" value="断开连接">
<hr>
消息内容:<input type="text" id="content">目标用户:<input type="text" id="to"><input type="button" value="发送" id="send">
<div id="conversation"></div>
<script>$(function () {$("#connect").click(function () {connect();})$("#disconnect").click(function () {if (stompClient != null) {stompClient.disconnect();}setConnected(false);})$("#send").click(function () {stompClient.send('/app/chat', {}, JSON.stringify({'to': $("#to").val(),'content': $("#content").val()}))})})var stompClient = null;function connect() {var socket = new SockJS('/chat');stompClient = Stomp.over(socket);stompClient.connect({}, function (success) {setConnected(true);stompClient.subscribe('/user/chat', function (msg) {showGreeting(JSON.parse(msg.body));});})}function showGreeting(msg) {$("#conversation").append('<div>' + msg.from + ':' + msg.content + '</div>');}function setConnected(flag) {$("#connect").prop("disabled", flag);$("#disconnect").prop("disabled", !flag);if (flag) {$("#chat").show();} else {$("#chat").hide();}}
</script>
</body>
</html>

这篇关于webSocket入门小案例(搭建实时交互的群聊+点对点的交流)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/557373

相关文章

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成