网页版五子棋—— WebSocket 协议

news2024/11/26 10:35:59

目录

·前言

一、背景介绍

二、原理解析

1.连接过程(握手)

2.报文格式

三、代码示例

1.服务端代码

(1)TestAPI 类

(2)WebSocketConfig 类

2.客户端代码

3.代码演示 

·结尾


·前言

        从本篇文章开始,我就来与大家分享网页版五子棋项目的一个实现过程了,这个项目一共有以下几个核心模块:用户模块、匹配模块、对战模块,后面文章会按照顺序来对每个模块进行介绍,并且此项目用到的核心技术有:Spring/SpringBoot/SpringMVC、WebSocket、MySQL、MyBatis、HTML/CSS/JS/AJAX,本篇文章来介绍一下 WebSocket 协议的内容、原理及代码示例,下面就开始本篇文章的内容介绍。

一、背景介绍

        WebSocket 是一种支持网页端与服务端保持长连接的消息推送机制,什么是消息推送机制呢?在我们传统的 web 程序中,都是属于“一问一答”的形式,如下图所示:

         这种情况下,服务器是被动的一方,如果客户端不主动发送请求,服务器就不会主动给客户端响应,我们所要编写的五子棋程序使用这种形式就会出现下面的情况:

        此时由于玩家2 没有向服务器发送请求,就会导致玩家2 收不到玩家1 的落子情况,消息推送机制就是可以让服务器主动给客户端发送数据,如果想使用传统“一问一答”的形式实现消息推送的效果也是可以做到,那就要采用“轮询”的方式,如下图所示:

         此时,在玩家1 没有落子之前,玩家2 就会以一定的时间间隔不断的向服务器发起请求,来询问玩家1 有没有落子,很明显,使用这种轮询操作的体验效果与开销与询问的时间间隔有关,关系如下:

  • 如果轮询时间间隔比较长:玩家1 落子之后,玩家2 不能及时获取到落子结果,对弈的体验性降低;
  • 如果轮询时间间隔比较短:虽然及时性得到改善,但是玩家2 就要浪费更多的机器资源,比如:网络带宽。

         为了更好的实现消息推送机制,在我们五子棋项目中,就引入了 WebSocket 协议,这是一种接近于 TCP 级别的通信方式,一旦建立好连接,客户端与服务器都可以主动向对方发送数据。

        基于 WebSocket 来实现的消息推送在五子棋项目中就会起到下图的效果:

         此时,玩家1 的落子请求发送给服务器后,服务器就会自动把响应推送给玩家1 与玩家2 。

二、原理解析

1.连接过程(握手)

        在我们使用网页端想尝试和服务器建立 WebSocket 连接会经过以下几个步骤:

  1. 网页端先给服务器发送一个 HTTP 请求,请求中会带有特殊的 header(Connection:Upgrade、Upgrade:WebSocket)这个 header 就是告诉服务器,我们需要进行协议的升级;
  2. 如果服务器支持 WebSocket,就会返回一个特殊的 HTTP 响应,这个响应的状态码是 101 (切换协议);
  3. 客户端与服务器之间开始使用 WebSocket 来进行通信。

        上述的具体过程可以如下图所示:

2.报文格式

        WebSocket 的报文格式如下图所示:

        WebSocket 也是一种应用层的协议,它的下层是基于 TCP 的,下面我来对上图的部分内容做一个简单介绍:

  •  FIN:当这里的内容为 1 时,表示要断开 WebSocket 连接;
  • RSV1~3:这是保留位,一般为0;
  • opcode:这是操作码,描述了当前 WebSocket 报文是什么类型,它可以描述当前报文是一个文本帧还是一个二进制帧,是一个 ping 帧还是一个 pong 帧;
  • Payload length:这是表示当前数据报携带的数据载荷的长度,它是一个可边长的字段,一个 WebSocket 的数据报能承载的载荷长度是非常长的;
  • Payload data:这是表示当前 WebSocket 实际报文要传输的数据载荷。

三、代码示例

        下面我来实现一个简单的 WebSocket 代码,这里服务端的代码由 Java 来编写,客户端的代码由 JS 来编写。

1.服务端代码

        编写服务端代码的流程如下:

  1. 创建出一个 Spring 项目,在 Spring 中内置了 WebSocket 可以直接使用;
  2. 创建 api.TestAPI 类,这个类用来处理 WebSocket 请求,并返回响应;
  3. 创建 config.WebSocketConfig 类,这个类用来配置请求路径和 TextWebSocketHandler 之间的对应关系。

         代码结构如下所示:

(1)TestAPI 类

         在这里,继承了 TextWebSocketHandler 这个类,我们需要重写里面的几个方法,如下图所示的选中方法:         关于重写的这四个方法都是什么作用,我在代码的注释中会进行详细的标注,那么关于 TestAPI 这个类的全部代码及注释如下所示:

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.TextWebSocketHandler;

// 添加 @Component 注解,交给 Spring 管理
@Component
public class TestAPI extends TextWebSocketHandler {
    @Override
    // 连接就绪后就会触发这个方法来告知连接成功
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("连接成功");
    }

    @Override
    // 客户端/服务器 给 服务器/客户端 发送信息通过这个方法就可以接收到信息
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("收到消息" + message.getPayload());
        // 让服务器收到消息之后原封不动的返回
        session.sendMessage(message);
    }

    @Override
    // 传输出现异常就会触发这个方法
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("连接异常");
    }

    @Override
    // 如果客户端/服务器关闭连接就会执行这个方法
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("连接关闭");
    }
}

(2)WebSocketConfig 类

         在这里,实现了 WebSocketConfigurer 接口,用于 WebSocket 的相关配置,代码及介绍注释如下所示:

import com.example.springgobang.aip.TestAPI;
import org.springframework.beans.factory.annotation.Autowired;
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;

// @EnableWebSocket 注解用来告诉 Spring 这是配置 WebSocket 的类
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    // 自动注入
    @Autowired
    private TestAPI testAPI;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 当客户端连接 /test 这样的路径后就会触发 testAPI 进而调用其内部的方法
        registry.addHandler(testAPI,"/test");
    }
}

2.客户端代码

        这里我们编写一个 html 页面来与服务器代码建立 WebSocket 连接,TestAPI.html 页面代码及介绍如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!--输入框-->
    <input type="text" id="message">
    <!--按钮-->
    <button id="sendButton">发送</button>

    <script>
        // 创建 WebSocket 实例, 要保证这里的路径与配置的路径一致 /test
        let webSocket = new WebSocket("ws://127.0.0.1:8080/test");
        // 连接成功后会调用这个函数
        webSocket.onopen = function() {
            console.log("连接成功");
        }
        // 收到信息后会调用这个函数
        webSocket.onmessage = function(e) {
            console.log("收到消息: " + e.data);
        }
        // 连接异常时会执行这个函数
        webSocket.onerror = function() {
            console.log("连接异常");
        }
        // 连接断开后会调用这个函数
        webSocket.onclose = function() {
            console.log("连接关闭");
        }
        // 实现点击按钮后,通过 WebSocket 发送请求
        let messageInput = document.querySelector('#message');
        let sendButton = document.querySelector('#sendButton');
        sendButton.onclick = function() {
            console.log("发送消息: " + messageInput.value);
            // send 函数就会把输入框中的内容发送出去
            webSocket.send(messageInput.value);
        }
    </script>
</body>
</html>

3.代码演示 

        此时,关于 WebSocket 的演示代码就编写完毕了,下面我们来启动程序,在电脑的浏览器上输入:http://127.0.0.1:8080/TestAPI.html 来访问 TestAPI.html 页面,然后鼠标右键点击检查,或者按键盘上的 F12 按钮,进入控制台观察日志信息,然后在输入框中输入数据点击发送就可以观察到效果,具体的效果演示如下图所示:

        此时在服务端断开连接(停止程序),结果如下图所示:

        通过上述的运行结果可以看出来,服务端可以随时调用 session.sendMessage() 方法来给客户端发送响应,从而可以实现消息推送这样的机制。

·结尾

        文章到此就要结束了,本篇文章介绍了 WebSocket 协议的一些基础原理,并用 WebSocket 进行了简单的网络编程,来演示了消息推送的效果,这是五子棋项目重要逻辑的实现依据,使用 WebSocket 就可以保证对弈双方可以实时在页面上观察到对方的落子情况,介绍完 WebSocket 之后就要开始五子棋项目的正式编写了,如果对本篇文章的内容有所疑惑,欢迎在评论区进行留言,我们下一篇文章再见吧~~~

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

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

相关文章

鸿蒙应用开发:下载功能

鸿蒙系统不断发展&#xff0c;有与安卓、iOS 形成三足鼎立之势&#xff0c;且其在智能手机、智能穿戴、车载、家居等行业领域的应用越来越广泛。作为开发者&#xff0c;如何抓住鸿蒙生态崛起的机遇&#xff0c;解决开发挑战&#xff0c;创造更好的应用体验&#xff1f;欢迎您和…

小白直接冲!BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测

小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测效果一览基本介绍程序设计参考资料 效果一…

如何绘制产业链图谱?

绘制产业链图谱是一个系统性的工作&#xff0c;涉及到对产业的深入理解和分析。对于一般产业绘制产业图谱的步骤&#xff0c;我们可以参照以下流程&#xff1a; 1.明确目标产业链&#xff1a;确定要分析的产业链&#xff0c;比如新材料、新能源、智能制造等&#xff0c;这通常…

Pycharm,2024最新专业版下载安装配置详细教程!

先来一段官方介绍&#xff0c;PyCharm是一种PythonIDE&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外&#xff0c;该IDE提供了一些高级功能…

鸿蒙开发——进程模型与进程通信

1、进程模型 ❓ 什么是进程&#xff1f; 进程是一个正在执行的程序的实例。当我们启动一个程序时&#xff0c;操作系统会创建一个进程&#xff0c;分配给它所需的资源&#xff0c;如内存和CPU时间。每个进程至少有一个线程&#xff0c;即执行线程&#xff0c;负责执行程序的指…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…

[大模型]Diffusion扩散式生成模型

一、概述 扩散式生成模型相较于GAN网络的对抗式生成模型&#xff0c;有更高的精度&#xff0c;也更符合人类的视觉和审美罗技&#xff0c;且风格化能力更强。现行的所有Diffusion模型都是基于2020年的论文DDPM来实现的。 GAN网络通过使生成器(Generator)生成的模型尽可能的逼近…

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…

keil5的Debug调试时,卡在 LDR R0, =SystemInit,无法往后进行

解决办法&#xff1a;使用STM32Cube生成的工程文件时&#xff0c;勾选Use MicroLIB即可

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…

ai常见实验

参考链接https://arxiv.org/pdf/2410.19894 对比实验&#xff08;sota 表格&#xff09; -辅助信息可以体现 P F 等 可视化结果 &#xff08;图片形式&#xff09; 消融实验 超参数实验 &#xff08;有时候表示 有时候单独表格 看哪个参数好&#xff09; 部分消融和超参数…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Oracle OCP认证考试考点详解082系列12

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 56. 第56题&#xff1a; 题目 解析及答案&#xff1a; 关于企业管理器&#xff08;EM&#xff09;Express&#xff0c;以下哪两个陈述是…

任务:拟合曲面

3d 要拟合粗的蓝色曲面&#xff0c;剩下三条线是在3个平面的投影 1 2 3 4d

Python世界:自动化办公Word之批量替换文本生成副本

Python世界&#xff1a;自动化办公Word之批量替换文本生成副本 任务背景编码思路代码实现相关参考 任务背景 为提高办公效率&#xff0c;用python试手了一个word任务&#xff0c;要求如下&#xff1a; 给你一个基础word文档A&#xff0c;格式为docx&#xff0c;名字为&#xf…

如何检查雷池社区版 WAF 是否安装成功?

容器运行状态检查&#xff1a; 使用命令行检查&#xff1a;打开终端&#xff0c;连接到安装雷池的服务器。运行 docker ps 命令&#xff0c;查看是否有与雷池相关的容器正在运行。 如果能看到类似 safeline-mgt、safeline-tengine 等相关容器&#xff0c;并且状态为 Up&#x…

青少年编程能力等级测评CPA Python编程(一级)

青少年编程能力等级测评CPA Python编程(一级) &#xff08;考试时间90分钟&#xff0c;满分100分&#xff09; 一、单项选择题&#xff08;共20题&#xff0c;每题3.5分&#xff0c;共70分&#xff09; 下列语句的输出结果是&#xff08; &#xff09;。 print(35*2) A&a…

java学习2

一、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元 重复的代码、具有独立功能的代码可以抽取到方法中&#xff1b;提高代码的复用性和可维护性。 二、方法的格式 1.方法的格式定义&#xff1a; 最简单的方法定义 调用&#xff1a;playGame(); 带…

蓝牙资讯|苹果AirPods Pro 2推出听力测试、助听器和听力保护等功能

苹果推送iOS 18.1 系统版本更新&#xff0c;AirPods Pro 2 用户也在 iOS 18.1 中获得了强大的新功能。 运行固件 7B19 的 AirPods Pro 2 用户&#xff0c;搭配 iOS 18.1 系统的 iPhone&#xff0c;将获得三项强大的听力健康功能&#xff1a;听力测试、助听器和听力保护。 听力…