当前位置: 首页 > news >正文

websocket聊天(全源码)

区别:我认为的websocket和轮询的区别

轮询是客户端定期向服务端发送请求,目的是获取的信息

websocket则是服务端直接向客户端发送想要获取的信息

配置jdk17 idea 2022

代码

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.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>wsocket</artifactId><version>0.0.1-SNAPSHOT</version><name>wsocket</name><description>wsocket</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version></dependency><!-- websocket消息推送 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework</groupId>-->
<!--            <artifactId>spring-websocket</artifactId>-->
<!--            <version>6.0.9</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.apache.tomcat.embed</groupId>-->
<!--            <artifactId>tomcat-embed-websocket</artifactId>-->
<!--            <version>10.1.20</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.apache.tomcat.embed</groupId>-->
<!--            <artifactId>tomcat-embed-websocket</artifactId>-->
<!--            <version>9.0.78</version>-->
<!--        </dependency>--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.9</version></dependency><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-websocket</artifactId><version>10.1.20</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

 配置类

package com.example.wsocket.spring;import com.example.wsocket.java.WebSocketConfig;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;/***/
@Configuration
@EnableWebSocket
public class MyWsConfig implements WebSocketConfigurer {@ResourceMyWsHandler myWsHandler;@ResourceMyWsInterceptor myWsInterceptor;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myWsHandler,"/myWs1").addInterceptors(myWsInterceptor).setAllowedOrigins("*");}//访问的位置,设置拦截器,设置拦截范围
}

websocket周期设置

package com.example.wsocket.spring;import cn.hutool.core.text.StrBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;/**物理程序*/
@Component
@Slf4j
public class MyWsHandler extends AbstractWebSocketHandler {private static Map<String,SessionBean> sessionBeanMap;private static AtomicInteger clientIdMaker;private static StringBuffer stringBuffer;//初始化static {sessionBeanMap = new ConcurrentHashMap<>();clientIdMaker = new AtomicInteger(0);stringBuffer = new StringBuffer();}@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {super.afterConnectionEstablished(session);SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());sessionBeanMap.put(session.getId(),sessionBean);log.info(sessionBeanMap.get(session.getId()).getClientId()+"建立连接");stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+"进入了群聊<br/>");sendMessage(sessionBeanMap);}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {super.handleTextMessage(session, message);log.info(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload());stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload()+"<br/>");sendMessage(sessionBeanMap);}//异常时@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {super.handleTransportError(session, exception);if (session.isOpen()){session.close();}sessionBeanMap.remove(session.getId());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {super.afterConnectionClosed(session, status);int clientId = sessionBeanMap.get(session.getId()).getClientId();sessionBeanMap.remove(session);log.info(clientId+"关闭了连接");stringBuffer.append(clientId+"退出了群聊<br/>");sendMessage(sessionBeanMap);}public void sendMessage(Map<String,SessionBean> sessionBeanMap){for(String key:sessionBeanMap.keySet()){{try {sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(stringBuffer.toString()));} catch (IOException e) {log.info("出错啦");}}}}//    //定时任务
//    @Scheduled(fixedDelay = 2000)//多少秒执行1次
//    public void sendMessage() throws IOException {
//        for (String key:sessionBeanMap.keySet()){
//            sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(":心跳"));
//        }
//    }
}

拦截器

package com.example.wsocket.spring;import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;import java.util.Map;/*** @authorGH* @company www.1248163489.com*/
@Component
@Slf4j
public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {return super.beforeHandshake(request, response, wsHandler, attributes);}@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {super.afterHandshake(request, response, wsHandler, ex);}
}

sessionBean


import jakarta.websocket.Session;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.web.server.WebSession;
import org.springframework.web.socket.WebSocketSession;/*** @authorGH* @company www.1248163489.com*/
@Data
@AllArgsConstructorpublic class SessionBean {/****@param*/private WebSocketSession webSocketSession;private Integer clientId;
}

前端页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<p style="border: 1px solid black;width: 400px;height: 600px" id="talkMsg"></p>
<input id="message" />
<button id="sendBtn" onclick="sendMsg()">发送</button>
</body>
<script>let ws = new WebSocket("ws://localhost:8080/myWs1")ws.onopen=function (){}ws.onmessage=function (message) {document.getElementById("talkMsg").innerHTML = message.data}function sendMsg() {ws.send(document.getElementById("message").value)document.getElementById("message").value=""}
</script>
</html>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 探索Linux中的神奇工具:探秘tail命令的妙用
  • 【C++/STL】vector(常见接口、模拟实现、迭代器失效)
  • graspnet+Astra2相机实现部署
  • vue3使用Ant-Design组件a-table表格实现多层表头及合并单元格
  • JavaWeb-JS
  • pycharm画图猫和老鼠
  • Jenkins配置(插件/角色/凭证)
  • 文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑分布式光伏高效消纳与负荷损失最小的区域配电网应急资源协同配置策略》
  • 力扣 滑动窗口题目总结
  • javaEE—图书管理系统(基础代码版)
  • 基于Vue的应届毕业生财务管理系统-计算机毕业设计源码82886
  • Android 通过adb命令查看设备尺寸和设置
  • 代码随想录算法训练营第四十一天 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
  • 记一次绕过宝塔防火墙的BC站渗透
  • 美颜技术揭秘:美颜SDK与美颜接口的开发实践
  • [译]CSS 居中(Center)方法大合集
  • iOS 系统授权开发
  • jdbc就是这么简单
  • Making An Indicator With Pure CSS
  • Mysql优化
  • storm drpc实例
  • 排序(1):冒泡排序
  • 使用parted解决大于2T的磁盘分区
  • 树莓派 - 使用须知
  • 小试R空间处理新库sf
  • 运行时添加log4j2的appender
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • Java数据解析之JSON
  • ​HTTP与HTTPS:网络通信的安全卫士
  • #、%和$符号在OGNL表达式中经常出现
  • #HarmonyOS:基础语法
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)jdk与jre的区别
  • .bat批处理出现中文乱码的情况
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET 给NuGet包添加Readme
  • .net6+aspose.words导出word并转pdf
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • :如何用SQL脚本保存存储过程返回的结果集
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [012-1].第12节:Mysql的配置文件的使用
  • [Angular] 笔记 7:模块
  • [AutoSAR系列] 1.3 AutoSar 架构
  • [BZOJ] 2006: [NOI2010]超级钢琴
  • [BZOJ2208][Jsoi2010]连通数
  • [C/C++] -- 二叉树
  • [C++]: std::move
  • [CSS3备忘] transform animation 等
  • [FlareOn6]Overlong
  • [HackMyVM]靶场Boxing