WebSocket网络协议

news2025/1/13 19:46:46

二十六、WebSocket

26.1 介绍

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

HHTP协议和WebSocket协议对比

  • HTTP是短连接
  • WebSocket是长连接
  • HTTP通信是单向的,基于请求响应模式
  • WebSocket支持双向通信
  • HTTP和WebSocket底层都是TCP连接

在这里插入图片描述

**思考:**既然WebSocket支持双向通信,功能看似比HTTP强大,那么我们是不死可以基于WebSocket开发所有的业务功能?

WebSocket缺点

服务器长期维护长连接需要一定的成本

各个浏览器支持程度不一样

WebSocket是长连接,受网络限制比较大,需要处理好重连

结论:WebSocket并不能完全取代HTTP,它只适合在特定的场景下使用

WebSocket应用场景:

1). 视频弹幕

v

2). 网页聊天

3). 体育实况更新

在这里插入图片描述

4). 股票基金报价实时更新

26.2 入门案例

26.2.1 案例分析

需求:实现浏览器与服务器的全双工通信。浏览器既可以向服务器发送消息,服务器也可主动向浏览器推送消息。

效果展示:

实现步骤

  1. 直接使用websocket.html页面作为WebSocket客户端
  2. 导入WebSocket的maven坐标
  3. 导入WebSocket服务端组件的WebSocketServer,用于和客户端通信
  4. 导入配置类WebSocketConfiguration,注册WebSocket的服务端组件
  5. 导入定时任务类WebSocketTask,定时向客户端推送数据
26.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);

    //判断当前浏览器是否支持WebSocket
    if('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坐标

在sky-server模块pom.xml中已定义

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

3). 定义WebSocket服务端组件(资料中已提供)

直接导入到sky-server模块即可

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();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @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);
    }

    /**
     * 群发
     *
     * @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的服务端组件(从资料中直接导入即可)

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 {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

5). 定义定时任务类,定时向客户端推送数据(从资料中直接导入即可)

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 {
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 通过WebSocket每隔5秒向客户端发送消息
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void sendMessageToClient() {
        webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
    }
}

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

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

相关文章

选购护眼台灯,全网都没有说清一个关键点!——照度均匀度

网上关于护眼台灯的选购推荐帖子多如牛毛&#xff0c;好台灯选购要点大体可归纳为以下五点&#xff1a; RG0无蓝光危害&#xff08;豁免级蓝光危害&#xff0c;RG1为低蓝光危害、RG2、RG3分别为中度和高危危害&#xff09; 无眩光&#xff0c;无可视频闪&#xff08;不刺眼…

tensorboard报错解决:No dashboards are active for the current data set

版本&#xff1a;tensorboard 2.10.0 问题&#xff1a;文件夹下明明有events文件&#xff0c;但用tensorboard命令却无法显示。 例如&#xff1a; 原因&#xff1a;有可能是文件路径太长了&#xff0c;导致系统无法读取文件。在win系统中规定&#xff0c;目录的绝对路径不得超…

Java通过JNI技术调用C++动态链接库的helloword测试

JNI调用原理 原理就不细说了&#xff0c;其实就是写个库给Java调&#xff0c;可以百度一下Java JNI&#xff0c;下面是HelloWorld代码测试 编写一个本地测试类 package com.my.study.cpp_jni;/*** 测试Java调用C库* <p>使用命令javac -h . NativeTest.java自动生成C头…

相机突然断电,保存的DAT视频文件如何打开

3-6 本文主要解决因相机突然断电导致拍摄的视频文件打不开的问题。 在平常使用相机拍摄视频&#xff0c;比如使用佳能相机拍摄视频的时候&#xff0c;如果电池突然断电&#xff0c;就非常有可能会导致视频没来得及保存而损坏的情况&#xff0c;比如会产生下图中的这种DAT文件…

云端部署ChatGLM-6B

大模型这里更新是挺快的&#xff0c;我参考的视频教程就和我这个稍微有些不一样&#xff0c;这距离教程发布只过去4天而已… 不过基本操作也差不多 AutoDL算力云&#xff1a;https://www.autodl.com/home ChatGLM3&#xff1a;https://github.com/THUDM/ChatGLM3/tree/main Hug…

Linux进程的认识与了解[上]

文章目录 1.何为进程?1.1对进程的认识1.2基本概念 2.OS如何管理大量进程?2.1图解2.2进程的形成 3.何为PCB?3.1对PCB的认识3.2task_ struct内容分类3.2对进程表的认识 4.查看进程4.1基础指令4.2获取某进程的PID(process id)4.3杀死进程4.4获取当前进程的父进程的ppid(parent …

王道数据结构课后代码题p40 9.给定一个带表头结点的单链表,写出算法 : 按递增次序输出单链表中各结点的数据元素并释放结点 (c语言代码实现)

本题代码如下&#xff08;有注释&#xff09; void delete_min(linklist* head) {while ((*head)->next ! NULL)//循环到只剩下头节点{lnode* pre *head;//pre为元素最小结点的前驱结点指针lnode* p (*head)->next;//p为工作指针lnode* q;//指向被删除的结点while (p-…

STM32 寄存器配置笔记——GPIO配置输出

一、概述 本文主要介绍GPIO 作为输出时的寄存器配置。包括时钟配置&#xff0c;输出模式配置。以STM32F10xxx系列为例&#xff0c;配置PA8、PD2端口作为输出&#xff0c;输出高/低电平。 二、配置流程 1&#xff09;GPIO外设时钟 通过查找STM32F10xxx中文参考手册得知&#xf…

【MySQL系列】 第二章 · SQL(中)

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Accelerate 0.24.0文档 一:极速入门

文章目录 一、概述1.1 PyTorch DDP1.2 Accelerate 分布式训练简介1.2.1 实例化Accelerator类1.2.2 将所有训练相关 PyTorch 对象传递给 prepare()方法1.2.3 启用 accelerator.backward(loss) 1.3 Accelerate 分布式评估1.4 accelerate launch 二、Accelerate 进阶2.1 notebook_…

Xshell远程登录 Linux小键盘数字输入变成字母解决办法

Xshell的设置问题&#xff0c;依次查看&#xff1a;文件-->属性-->终端-->VT模式-->初始数字键盘模式更改为&#xff1a;设置普通&#xff08;s&#xff09;

OpenGL_Learn09(摄像机)

1. 摄像机环绕观察 texture两个文件以及shader就是之前的版本 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include "stb_image.h" #include <cmath> #include "shader.h"#include <glm/glm.hpp>…

指标体系:洞察变化的原因

一、指标概述 指标体系是指根据运营目标&#xff0c;整理出可以正确和准确反映业务运营特点的多个指标&#xff0c;并根据指标间的联系形成有机组合。 指标体系业务意义极强&#xff0c;所有指标体系都是为特定的业务经营目的而设计的。指标体系的设计应服从于这种目的&#x…

3DMAX如何渲染室内效果图?

这可能不是最好的教程,但对于3dmax初学者来说,它具有一定的学习价值和启示意义。 任何在建筑或室内设计领域工作并需要室内或外部空间“艺术家渲染”的人都会熟悉行业巨头Autodesk发布的3ds Max。 3ds Max是此类工作的默认标准,不是因为它在其他3D程序中无法完成,而是因为它…

计算机网络课后作业2023秋

计算机网络第三版吴功宜版 课后作业 第一章作业三、计算与问答3.73.8 第二章作业三、计算与问答3.23.53.6 第三章作业三、计算与问答3.13.53.73.8 第四章作业三、计算与问答3.13.2 第五章作业三、计算与问答3.13.33.4 第一章作业 三、计算与问答 3.7 3.8 第二章作业 三、计…

Vant 移动端UI 组件自动引入

Vue项目中安装Vant # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant 组件按需引入配置 Vant按需引入- - -安装&#xff1a;unplugin-vue-components 插件 unplugin-vue-components 插件可以在Vue文件中自动引入组件&#xff08;包括项目自身的组件和各种组件库中的组件&…

Leetcode—50.Pow(x,n)【中等】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—50.Pow(x,n) 实现代码 double recurPow(double x, long long n) {if(n 1) {return x;}double res recurPow(x, n / 2);if(n % 2 1) {return x * res * res;} else {return res * res;} }double myPow(double x, int…

链表OJ题【环形链表】(3)

目录 环形问题的思考 ❓Q1 ❓Q2 &#x1f642;Q2 ❓Q3 ❓Q4 8.环形链表 9.环形链表Ⅱ 今天接着链表的经典问题环形问题。大家一定要自己动手多写写。&#x1f642; 快慢指针&#xff08;保持相对距离/保持相对速度&#xff09;野指针考虑为NULL的情况带环链表&#x…

推荐系统笔记--Swing模型的原理

1--Swing模型的引入 在 Item CF 召回中&#xff0c;物品的相似度是基于其受众的交集来衡量的&#xff0c;但当受众的交集局限在一个小圈子时&#xff0c;就会误将两个不相似的物品定义为相似&#xff1b; Swing 模型引入用户的重合度来判断两个用户是否属于一个小圈子&#xff…

基于鲸鱼算法优化概率神经网络PNN的分类预测 - 附代码

基于鲸鱼算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于鲸鱼算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于鲸鱼优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…