持久双向通信网络协议-WebSocket-入门案例实现demo
1 介绍
WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输。
HTTP协议和WebSocket协议对比:
-
HTTP是短连接(一次响应完即消除)
-
WebSocket是长连接(持久连接)
-
HTTP通信是单向的,基于请求响应模式
-
WebSocket支持双向通信
-
HTTP和WebSocket底层都是TCP连接


思考:既然WebSocket支持双向通信,功能看似比HTTP强大,那么我们是不是可以基于WebSocket开发所有的业务功能?
WebSocket缺点:
服务器长期维护长连接需要一定的成本 各个浏览器支持程度不一 WebSocket 是长连接,受网络限制比较大,需要处理好重连
结论:WebSocket并不能完全取代HTTP,它只适合在特定的场景下使用
WebSocket应用场景:(数据实时更新)
1). 视频弹幕

2). 网页聊天
3). 体育实况更新
4). 股票基金报价实时更新
2 入门案例
2.1 案例分析
需求:实现浏览器与服务器全双工通信。浏览器既可以向服务器发送消息,服务器也可主动向浏览器推送消息。
效果展示:

实现步骤:
1). 直接使用websocket.html页面作为WebSocket客户端
2). 导入WebSocket的maven坐标
3). 导入WebSocket服务端组件WebSocketServer,用于和客户端通信
4). 导入配置类WebSocketConfiguration,注册WebSocket的服务端组件
5). 导入定时任务类WebSocketTask,定时向客户端推送数据 (效果演示)
2.2 代码开发
1). 定义websocket.html页面
<!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>
2). 导入maven坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
3). 定义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();}}}
}
4). 定义配置类,注册WebSocket的服务端组件

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();}
}
5). 定义定时任务类,定时向客户端推送数据 (体现测试效果!!!*)

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()));}
}
2.3 功能测试
启动服务,打开websocket.html页面
浏览器向服务器发送数据:

服务器向浏览器间隔5秒推送数据:

相关文章:
持久双向通信网络协议-WebSocket-入门案例实现demo
1 介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输。 HTTP协议和WebSocket协议对比: HTTP是短连接࿰…...
LV.13 D10 Linux内核移植 学习笔记
具体实验步骤在lv13day10 实验十 一、Linux内核概述 1.1 内核与操作系统 内核 内核是一个操作系统的核心,提供了操作系统最基本的功能,是操作系统工作的基础,决定着整个系统的性能和稳定性 操作系统 操作系统是在内核的基础上添…...
STM32面试体验和题目
目录 一、说一下你之前的工作主要干了什么? 二、stm32有关的知识点 1.stm32的外设有哪一些 2.你的毕业论文的项目里面是怎么设计的 三,C语言的考察 1.写一个结构体(结构体的内容自由发挥) 2.写一个指针型的变量 3.结构体是…...
微软.NET、.NET Framework和.NET Core联系和区别
我是荔园微风,作为一名在IT界整整25年的老兵,看到不少初学者在学习编程语言的过程中如此的痛苦,我决定做点什么,我小时候喜欢看小人书(连环画),在那个没有电视、没有手机的年代,这是…...
Shell脚本同时调用#!/bin/bash和#!/usr/bin/expect
如果你想在一个脚本中同时使用bash和expect,你可以将expect部分嵌入到bash脚本中。以下是一个示例: #!/bin/bash# 设置MySQL服务器地址、端口、用户名和密码 MYSQL_HOST"localhost" MYSQL_PORT"3306" MYSQL_USER"your_usernam…...
C++ Webserver从零开始:基础知识(一)——Linux网络编程基础API
目录 前言 一.socket地址API 1.主机字节序和网络字节序 2.通用socket地址 3.专用socket地址 二.创建socket 三.绑定socket(命名socket) 四.监听socket 五.接受连接(服务端) 六.发起连接(客户端) 七.关闭连接…...
cookie和session的工作过程和作用:弥补http无状态的不足
cookie是客户端浏览器保存服务端数据的一种机制。当通过浏览器去访问服务端时,服务端可以把状态数据以key-value的形式写入到cookie中,存储到浏览器。浏览器下次去服务服务端时,就可以把这些状态数据携带给服务器端,服务器端可以根…...
【蓝桥杯选拔赛真题30】C++字母转换 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析
目录 C/C++字母转换 一、题目要求 1、编程实现 2、输入输出...
资产负债表#通俗易懂
资产负债表(the Balance Sheet)亦称财务状况表,表示企业在一定日期(通常为各会计期末)的财务状况(即资产、负债和业主权益的状况)的主要会计报表。 (99 封私信 / 11 条消息) 能通俗易懂的给小白…...
PCF8563转STM32 RTC避坑指南
问题一,时间读取错误 原因,读写时间必须Time在前,Date在后 HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BCD); HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BCD); HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BCD); …...
前端重置密码报错记录
昨天晚上,我写了重置密码的前端,测试的时候报错 今天上午,我继续试图解决这个问题,我仔细检查了一遍,前端没有问题 可以正常接收输入的数据并且提交 但是后端接收到的数据为空,后端接口也没有问题 但后端收…...
css3的过度效果transition支持哪些属性,Transition 所支持的css属性
transition-property是用来指定当元素其中一个属性改变时执行transition效果: 所支持的属性类型如下: 名称描述属性color: 通过红、绿、蓝和透明度组件变换(每个数值处理) 如: background-color, border-color, color, outline-co…...
JAVAEE初阶 文件IO(一)
这里写目录标题 一. 计算机中存储数据的设备1.1 CPU1.2 内存1.3 硬盘1.4 三种存储的区别 二.文件系统2.1 相对路径2.2 绝对路径2.3 .和..的含义2.4 例子2.5 everything工具 三.文件3.1 文本文件3.2 二进制文件 四. JAVA对于文件的API4.1 getParent getName getPath getAbsolute…...
使用WAF防御网络上的隐蔽威胁之CSRF攻击
在网络安全领域,除了常见的XSS(跨站脚本)攻击外,CSRF(跨站请求伪造)攻击也是一种常见且危险的威胁。这种攻击利用用户已经验证的身份在没有用户知情的情况下,执行非授权的操作。了解CSRF攻击的机…...
如何从 Keras 中的深度学习目录加载大型数据集
一、说明 数据集读取,使用、在磁盘上存储和构建图像数据集有一些约定,以便在训练和评估深度学习模型时能够快速高效地加载。本文介绍Keras 深度学习库中的ImageDataGenerator类等工具自动加载训练、测试和验证数据集。 二、ImageDataGenerator加载数据集…...
【大数据】Flink 详解(八):SQL 篇 Ⅰ
《Flink 详解》系列(已完结),共包含以下 10 10 10 篇文章: 【大数据】Flink 详解(一):基础篇【大数据】Flink 详解(二):核心篇 Ⅰ【大数据】Flink 详解&…...
如何从命令行运行testng.xml?
目录 创建一个新的java项目并从命令行运行testng.xml 使用命令行运行XML文件 从命令行运行现有maven项目的XML文件 在这篇文章中,我们将使用命令行运行testng.xml。有多种场景需要使用命令行工具运行testng.xml。也许您已经创建了一个maven项目,现在想…...
MongoDB-数据库文档操作(2)
任务描述 文档数据在 MongoDB 中的查询和删除。 相关知识 本文将教你掌握: 查询文档命令;删除文档命令。 查询文档 我们先插入文档到集合 stu1 : document([{ name:张小华, sex:男, age:20, phone:12356986594, hobbies:[打篮球,踢足球…...
文件包含介绍
本地文件包含 常见的文件包含漏洞的形式为 <?php include("inc/" . $_GET[file]); ?> 考虑常用的几种包含方式为 同目录包含file.htaccess目录遍历?file…/…/…/…/…/…/…/…/…/var/lib/locate.db日志注入?file…/…/…/…/…/…/…/…/…/var/log/a…...
C语言——小细节和小知识9
一、大小端字节序 1、介绍 在计算机系统中,大小端(Endianness)是指多字节数据的存储和读取顺序。它是数据在内存中如何排列的问题,特别是与字节顺序相关。C语言中的数据存储大小端字节序指的是在内存中存储的多字节数据类型&…...
软文SEO的常见指标有哪些_如何撰写有吸引力的软文标题
<h2>软文SEO的常见指标有哪些</h2> <p>在当今的数字营销领域,软文(Soft Article)已经成为推动网站流量和品牌知名度的重要工具。要让软文真正发挥作用,我们必须了解软文SEO的常见指标,这些指标可以帮…...
PHP PhantomJS 安装与使用指南
PHP PhantomJS 安装与使用指南 【免费下载链接】php-phantomjs Execute PhantomJS commands through PHP 项目地址: https://gitcode.com/gh_mirrors/ph/php-phantomjs 1. 项目目录结构及介绍 在安装jonnnnyw/php-phantomjs库后,您将得到一个基本的目录结构…...
圆形光斑激光熔覆 Comsol 仿真:科研利器已就位
圆形光斑激光熔覆comsol仿真模型,模型已通过实验验证了正确性,确保模型一定正确可用于科研。 高斯热源,马兰戈尼效应,粘性耗散力等,激光熔覆过程必要项均考虑在模型中。 可根据自己需要调整工艺参数,做完对…...
WebAgent :基于 MCP 协议打造的智能应用“超级路由器”
本文由云软件体验技术团队李锦浩原创。 在 NextSDK 介绍文章里,我们聊了怎么用 opentiny/next-sdk 给前端页面快速接入智能化能力——几行代码嵌进去,用户扫个二维码,手机上就能弹出一个 Remoter 对话窗口,直接用自然语言远程操控…...
dexcount-gradle-plugin最佳实践:提升Android应用性能的10个技巧
dexcount-gradle-plugin最佳实践:提升Android应用性能的10个技巧 【免费下载链接】dexcount-gradle-plugin A Gradle plugin to report the number of method references in your APK on every build. 项目地址: https://gitcode.com/gh_mirrors/de/dexcount-grad…...
DBNet++的ASF模块真的只是空间注意力吗?深入对比论文与官方代码的三种实现
DBNet的ASF模块:论文与代码的注意力机制差异深度解析 在文本检测领域,DBNet因其出色的性能和实时性成为工业界和学术界的热门选择。其核心创新之一——自适应尺度融合(ASF)模块,在论文中被描述为空间注意力机制&#x…...
GESP三级语法知识(六、string 入门与基础操作)
🌟 第一课:《string 入门与基础操作》🏰 第一章:string 是什么?(升级版小火车)1、🎯 故事以前我们用的是:👉 char数组 小火车 🚂(要自…...
仅剩最后3家银行未完成Java Istio全面替换——这份含12类Java Agent冲突检测脚本、4种Sidecar注入模式对比的适配手册即将下线
第一章:Java Istio适配现状与收官倒计时Istio 1.20 是最后一个官方支持 Java 客户端(istio-java-api)的版本,自 1.21 起,Istio 社区正式移除了对 Java SDK 的维护和 CI 验证。这一决策标志着 Java 生态在 Istio 原生控…...
智汇云舟亮相2026中关村论坛 联合发起“通智行业大脑”联盟
3月29日,作为中关村论坛年会的重要组成部分,“迈向通用人工智能”平行论坛在中关村国家自主创新示范区展示交易中心隆重举行。本次论坛由北京市科学技术委员会、中关村科技园区管理委员会、北京市海淀区人民政府联合主办,北京通用人工智能研究…...
Swin2SR权限控制系统搭建:从小白到部署的完整实战教程
Swin2SR权限控制系统搭建:从小白到部署的完整实战教程 1. 引言:从个人工具到团队服务的转变 你刚刚体验了Swin2SR的强大,一张模糊的老照片,几秒钟就变得清晰锐利,那种感觉就像给图片做了一次“数字近视手术”。但很快…...
