三步学会使用WebSocekt

目录

一 什么是websocket

二 如何使用websocket

1.导入websocket的maven坐标

2.创建websocket的服务类 

3.创建websocket的配置类

4.按需求实现业务逻辑

5.前端实现websocket


一 什么是websocket

        websocket和HTTP一样是基于TCP的一个通信协议。不过他是支持客户端和服务端双向通信的协议 。

        和HTTP不同的是,websocket是长连接 , HTTP是短连接 ,因为websocket只要客户端可服务端建立好了连接,除了主动关闭连接 , 他们发送完信息不会自动断开 , 而HTTP客户端向服务端发送一次连接,服务端返回后,就会断开连接 , 下次再发就要重新建立连接。

        而且HTTP只能是客户端主动向服务端发送信息 , 服务端接收,然后再返回。而websockt的服务端和客户端的通信是双向的,客户端可以主动向服务端发送信息 , 服务端也可以主动向客户端发送信息。

二 如何使用websocket

1.导入websocket的maven坐标

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

2.创建websocket的服务类 

package com.sky.websocket;import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")  //连接路径
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}/*** 连接关闭调用的方法** @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}/*** 群发** @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

① 你可以把这个类看成一个websocket的Controller类,因为前端页面(客户端)会设置一个连接服务端websocket的路径,就是

@ServerEndpoint("/ws/{sid}")  //连接路径

这个路径,需要和前端保持一致。

② 然后连接成功之后 , 就会创建一个连接对象 , 把客户端连接对象存储到

private static Map<String, Session> sessionMap = new HashMap();

③ 这个map集合中,String就是上面的{sid}这个参数是前端传来的,作为对象的标识。

剩下的

onOpen()

方法上面加了注解 , 只要客户端与服务端连接成功 , 就会自动调用这个方法。

④ 还有下面这个方法

/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);
}

这个方法是收到客户端发送的信息(页面) ,就会自动调用这个方法 , 同时把客户端的标识已经客户端发送的信息当作参数传来。

⑤ 还有这个关闭连接的方法

/*** 连接关闭调用的方法** @param sid*/
@OnClose
public void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);
}

这个方法是在我们关闭连接的时候自动执行。

⑥ 最后一个方法

public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}
}

这个方法上面没有任何注解 , 也就是说不能自动执行 , 需要我们调用才会执行 , 他的主要作用就是服务端向客户端发送信息 , 而且我们可以按照需求 , 在不同的逻辑下按需要调用这个方法,来向客户端发送信息 。而且这里是群发 ,因为我是直接遍历map集合中的所有客户端对象进行发送。

3.创建websocket的配置类

package com.sky.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类,用于注册WebSocket的Bean*/
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

这个配置类主要用于创建websocket的Bean来做一些初始化

4.按需求实现业务逻辑

        在这里websocket基本配置已经完成了,最后只需要按照自己业务需求去与客户端进行通信就可以了 ,我在这里做一个示例:

        比如我需要每3秒向客户端发送当前时间的信息,而客户端可以主动向服务端发送信息。

        所以这里我就需要使用定时任务springTask来实现这个业务逻辑,每3秒调用向客户端发送信息的方法。实现代码如下:

package com.sky.task;import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5秒向客户端发送消息*/@Scheduled(cron = "0/5 * * * * ?")public void sendMessageToClient() {webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}
}

 

5.前端实现websocket

        前端也需要实现websocket相关代码,但是代码都是一样的 , 所以我这里直接将我的前端代码给大家展示出来:

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>WebSocket Demo</title>
</head>
<body><input id="text" type="text" /><button onclick="send()">发送消息</button><button onclick="closeWebSocket()">关闭连接</button><div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;var clientId = Math.random().toString(36).substr(2);//判断当前浏览器是否支持WebSocketif('WebSocket' in window){//连接WebSocket节点websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);}else{alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function(){setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(){setMessageInnerHTML("连接成功");}//接收到消息的回调方法websocket.onmessage = function(event){setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose = function(){setMessageInnerHTML("close");}//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function(){websocket.close();}//将消息显示在网页上function setMessageInnerHTML(innerHTML){document.getElementById('message').innerHTML += innerHTML + '<br/>';}//发送消息function send(){var message = document.getElementById('text').value;websocket.send(message);}//关闭连接function closeWebSocket() {websocket.close();}
</script>
</html>

 最终演示结果如下:

以上就是websocket的基本使用 , 主要代码都是一样的,使用时直接cv即可,只需要实现自己的需求逻辑这部分代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/39025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1688商品采集用什么?【1688采集API接口】无视大量复制-同行店铺采集-批量全店采集-包邮商品采集

功能亮点&#xff1a; 1688同行店铺采集&#xff0c;1688批量全店采集&#xff0c;1688包邮商品采集&#xff0c;仅采集一件代发产品&#xff0c;采集发货时间&#xff0c;比如48小时发货&#xff0c;1688运费价格采集:可以采集运费价格 功能介绍二&#xff1a; 仅采集一件代…

数据结构与算法笔记:高级篇 - 并行算法:如何利用并行处理提高算法的执行效率?

概述 时间复杂度是衡量算法执行效率的一种标准。但是&#xff0c;时间复杂度并不能跟性能划等号。在真是的软件开发中&#xff0c;即便在不降低时间复杂度的情况下&#xff0c;也可以通过一些优化手段&#xff0c;提升代码的执行效率。毕竟&#xff0c;对于实际的软件开发来说…

Android Compose 十二:常用组件列表 上拉加载

列表 上拉加载 当前思路 判断 列表最后一个显示的条目 为 数据集合的长度-1 用来记录刷新状态 var refreshing by remember {mutableStateOf(false)}数据集合 val list remember{List(10){"条目》》${it}"}.toMutableStateList()}用来记录列表当前状态及状态变化…

行业分析---造车新势力之极氪汽车

1 前言 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 《行业分析-…

心跳机制简介

心跳机制 心跳机制&#xff08;Heartbeat Mechanism&#xff09;是一种用于监控和维护计算机系统、网络和分布式系统中各个节点之间连接状态的技术。它通过周期性地发送信号&#xff08;即“心跳”&#xff09;来确认系统组件之间的活跃性和可用性。如果某个节点没有在预期时间…

fastapi swagger js css 国内访问慢问题解决

fastapi swagger js css 国内访问慢问题解决 直接修改fastapi包中静态资源地址为如下地址 swagger_js_url: str "https://cdn.bootcdn.net/ajax/libs/swagger-ui/3.9.3/swagger-ui-bundle.js", swagger_css_url: str "https://cdn.bootcdn.net/ajax/libs/sw…

1971计算机毕业设计asp.net游乐园信息管理系统 VS开发access数据库web结构c#编程计算机网页源码项目

一、源码特点 asp.net游乐园信息管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 asp.net游乐园管理系统 二、功能介绍 前台功能&#xff1a; 1&#xff09;系统首页浏览 2&#xff09;园区通知浏…

leetcode-19-回溯-组合问题(剪枝、去重)

引自代码随想录 一、[77]组合 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] 1、大致逻辑 k为树的深度&#xff0c;到叶子节点的路径即为一个结果 开始索引保证不…

【计算机网络】网络层(作业)

【一】 1、某主机的 IP 地址为 166.199.99.96/19。若该主机向其所在网络发送广播 IP 数据报&#xff0c; 则目的地址可以是&#xff08;D&#xff09;。 A. 166.199.99.255B. 166.199.96.255C. 166.199.96.0D. 166.199.127.255 解析&#xff1a; 166.199.99.96/19166.199.0…

深入解读OkHttp3中的Dispatcher

OkHttp3是一个非常流行的HTTP客户端&#xff0c;用于与服务器通信。Dispatcher是OkHttp3中的一个关键组件&#xff0c;负责管理和调度请求。在这篇博客中&#xff0c;我们将深入探讨Dispatcher的工作原理、相关类的关系以及其实现细节。 什么是Dispatcher&#xff1f;&#x1…

STM32 看门狗 HAL

由时钟图可以看出看门狗采用的是内部低速时钟&#xff0c;频率为40KHz 打开看门狗&#xff0c;采用32分频&#xff0c;计数1250。 结合设置的分频系数和重载计数值&#xff0c;我们可以计算出看门狗的定时时间&#xff1a; 32*1250/40kHz 1s 主函数中喂狗就行 HAL_IWDG_Ref…

车载资料分享中:硬件在环、canoe、UDS诊断、OTA升级、TBOX测试

每日直播时间&#xff1a; 周一到周五&#xff1a;20&#xff1a;00-23&#xff1a;00 周六与周日&#xff1a;9&#xff1a;00-17&#xff1a;00 直播内容&#xff1a;&#xff08;车厂一比一测试&#xff09; HIL&#xff08;硬件在环&#xff09;测试、UDS功能诊断、UDS自动…

Java集合整理笔记

目录 1.集合基础概念 1.1 集合 1.2 单例集合 1.2.1 List系列 1、ArrayList 2、LinkedList 3、Voctor​编辑 1.2.2 Set系列 1、HashSet 集合 2、LinkedHashSet 集合 3、TreeSet集合 1.3 双例集合 1.3.1 HashMap 1.3.2 LinkedHashMap 1.3.3 TreeMap 1.4 快速失败…

小抄 20240630

1 大学和电视剧里演的大学&#xff0c;是两回事&#xff0c;不要带着电视剧的滤镜去看大学。 你的大学室友不一定能成为朋友&#xff0c;你的教官不一定有你情绪稳定&#xff0c;你的恋爱可能是杀猪盘&#xff0c;你的学长学姐给你领路可能只是为了高溢价卖你垃圾东西。 上大…

华为机试HJ2计算某字符出现次数

华为机试HJ2计算某字符出现次数 题目&#xff1a; 计算字符串中的某个字符出现的次数&#xff0c;不区分大小写。 想法&#xff1a; 将输入的字符串和要查询的字符变为小写&#xff0c;遍历整个字符串统计要查的字符个数。 input_str input().lower() check_str input()…

一篇搞懂!LinuxCentos中部署KVM虚拟化平台(文字+图片)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f468;‍&#x1f4bb;Linux高级管理专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月28日15点11分 &#x1f004;️文章质量&#xff1a;94分 目录 ————前言———— KVM的优点 KVM…

【embedding 神经网络】神经网络算法 —— Embedding(嵌入)!!

文章目录 前言 1、Embedding的本质 &#xff08;1&#xff09;机器学习中的Embedding &#xff08;2&#xff09;NLP中的Embedding 2、Embedding的原理 &#xff08;1&#xff09;Image Embedding&#xff08;图像嵌入&#xff09; &#xff08;2&#xff09;Word Embed…

geoserver添加 GeoTiff

GeoTIFF 是一种广泛使用的地理空间栅格数据格式。它由一个包含数据和地理参考信息的文件组成。本节提供添加和发布 GeoTIFF 文件的说明。 打开 Web 浏览器并导航到 GeoServer欢迎页面。 从界面中选择添加商店。 从可用的栅格数据源集合中选择GeoTIFF - 带有地理信息的标记图…

解决卡顿发热,超帧技术焕发中重载游戏动力

近几年&#xff0c;中国手游市场规模不断扩大&#xff0c;开发者通过在画面、玩法等方面的持续创新和打磨&#xff0c;推出更加精品化的产品。然而愈发精美的画质和复杂的玩法&#xff0c;也给硬件带来超高的负载&#xff0c;导致玩家在游戏过程中&#xff0c;频繁出现掉帧卡顿…

elementUI 年份范围选择器实现

elementUI 不支持年份范围的选择器&#xff0c;依照下面的文章进行修改和完善 el-year-picker&#xff1b; element日期选择范围、选择年份范围_elemet 两个日期 选择的年份范围必须在三年之内-CSDN博客 el-year-picker 组件&#xff1a; 依赖包&#xff1a;moment 属性&…