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

五子棋双人对战项目(1)——WebSocket介绍

目录

一、项目介绍

如何实现实时同步对局?

二、WebSocket

1、什么是WebSocket?

2、WebSocket的报文格式

opcode

payload len

payload data

3、WebSocket握手过程

4、WebSocket代码的简单编写

三、WebSocket 和 HTTP的关系

1、相同点:

2、不同点

3、联系


一、项目介绍

        五子棋双人对战项目一个Web项目,支持多个玩家联网匹配对局,主要有以下三个模块:

1、用户模块

用户的注册和登录。

管理用户的天梯分数、比赛场数、获胜场数。

2、匹配模块

依据用户的天梯积分,实现匹配机制。

3、对战模块

把两个匹配到的玩家放到一个游戏房间中。双方通过网页的形式进行对战。

关键技术:

Java,Spring/Spring Boot/Spring MVC,HTML/CSS/JS/AJAX,MySQL/MyBatis,WebSocket

如何实现实时同步对局?

        之前学习的服务器开发,主要使用的是下面这样的模型:

客户端:主动向服务器发起请求,服务器收到之后,返回一个响应。如果客户端不向服务器发送请求,服务器就不会给客户端返回响应。

        五子棋项目是要实现实时同步对局的,也就是对方落子后,我这边立马能更新棋盘,我落子后,对方也要能立即更新棋盘。

        基于之前学过的HTTP协议,如果我不向服务器发起请求,拿到最新棋盘数据,那么我这里的页面就一直不会改变。

        基于上面的问题,想到有以下2种解决方案:

1、客户端每隔一段时间向服务器发起请求,拿到最新的数据。

2、服务器主动给我们返回响应。

        第一个方案明显不行,如果间隔时间太短,发送请求的频率会非常高,也就意味着会浪费带宽,浪费资源;间隔时间太长,就可能导致对方已经落子了,但还在间隔时间中,那么我就要继续等客户端发起请求才能拿到最新的数据,明显也不合理。

        第二个方案可行,如果对方落子了,服务器接收到请求,主动给我返回响应,这很就合理了。

        服务器主动发送响应给客户端,这样的场景称之为:消息推送。

        那HTTP协议是否能实现 “消息推送” 场景呢?HTTP自身是难以实现这种消息推送效果的。如果要想实现这样的效果,就需要基于 “轮询” 的机制。而所谓的 “轮询” ,也就是上面的第一种方案,明显是不合理的,会白白浪费很多机器资源(尤其是带宽)。

        但有一种协议可以很轻松的实现轮询:WebSocket。


二、WebSocket

1、什么是WebSocket?

1、WebSocket 是HTML5下一种新的协议(WebSocket协议本质上是一个基于TCP的协议)

2、它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽,同时可以达到实时通讯的目的。

3、WebSocket是一个持久化的协议。

2、WebSocket的报文格式

opcode

描述了当前这个WebSocket报文是啥类型。比如:

表示当前这是一个文本帧,还是一个二进制;

表示当前这是一个 ping 帧,还是一个 pong 帧。

payload len

表示当前数据报携带的数据载荷长度。

这个字段本身就是一个变长的,一个WebSocket数据报能承载的载荷长度是非常长的。

payload data

实际报文要传输的数据载荷。

3、WebSocket握手过程

        使用网页端,尝试和服务器建立 WebSocket 连接,网页端会先给服务器发起一个 HTTP 请求,这个 HTTP 请求中会带有特殊的 header:

        ConnectionUpgrade

        UpgradeWebSocket

        如果服务器支持 WebSocket,就会返回一个特殊的 HTTP 响应。这个响应的状态码是 101(切换协议)。

        然后客户端和服务器之间就可以开始使用 WebSocket 来进行通信了。

4、WebSocket代码的简单编写

        引入依赖:

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

        后端代码:

@Component
public class TestWebSocket extends TextWebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("建立连接");
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        System.out.println("收到信息: " + message.getPayload());
    }

    @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("关闭连接");
    }
}

        指定路径:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    private TestWebSocket testWebSocket = new TestWebSocket();
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(testWebSocket, "/test");
    }
}

        前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TestWebSocket</title>
</head>
<body>
    <input type="text" id="message">
    <button id="submit">提交</button>
    
    <script>
        //创建websocket实例
        var 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发送请求
        var input = document.querySelector("#message");
        var button = document.querySelector("#submit");
        button.onclick = function() {
            console.log("发送信息: " + input.value);
            websocket.send(input.value);
        }
</script>
</body>
</html>

        运行程序:

        

        连接成功后,前端、后端都打印建立连接

        输入信息,点击提交

        关闭浏览器,后端打印

        这就是简单的WebSocket通信过程。


三、WebSocket 和 HTTP的关系

1、相同点:

1、都基于 TCP,都是可靠性传输协议。

2、都是应用层协议。

2、不同点

1、WebSocket 是双向通信协议,模拟Socket协议,可以双向发送或接收信息。

2、HTTP 是单向的。

3、WebSocket 是需要浏览器和服务器握手进行建立连接的。

4、HTTP是浏览器向服务器发起请求,从而建立连接,服务器预先并不知道这个连接。

3、联系

WebSocket在建立握手时,数据是通过HTTP传输的。但是建立连接成功后,真正传输时是不需要HTTP协议的。


http://www.kler.cn/news/327632.html

相关文章:

  • ubuntu 开启root
  • 太速科技-FMCJ457-基于JESD204B的2路2Gsps AD 2路2Gsps DA FMC子卡
  • LED驱动电路
  • SQL | 查询带有单引号的异常数据和replace与insert插入的区别
  • YOLO11震撼发布!
  • 《Python编程:从入门到实践》数据可视化
  • Linux操作系统中Redis
  • 从源码中学习动态代理模式
  • SpringBoot自定义异常
  • Webpack 4 优化指南:提升构建性能与加载速度
  • 服务器被挂马,导致网站首页被更改怎么解决
  • css的选择器及优先级
  • 在树莓派上基于 LNMP 搭建 Nextcloud
  • Leetcode 206. 反转链表
  • 环形链表的约瑟夫问题
  • 计算机网络基础--认识协议
  • 【测试】混沌工程
  • 滚雪球学MySQL[7.3讲]:数据库日志与审计详解:从错误日志到审计日志的配置与使用
  • [含文档+PPT+源码等]精品大数据项目-基于Django实现的高校图书馆智能推送系统的设计与实现
  • 中国雕塑——孙溟㠭浅析《瘗鹤铭》
  • jmeter中token测试
  • pycharm 配置篇
  • 鸡兔同笼,但是线性代数
  • ubuntu卸载VSFTPD
  • SSH远程连接保持长时间不断开
  • 鸿蒙NEXT开发-自定义构建函数(基于最新api12稳定版)
  • react+antdMobie实现消息通知页面样式
  • 大模型部署——NVIDIA NIM 和 LangChain 如何彻底改变 AI 集成和性能
  • 原生 React Native 和 Expo对比
  • 玄武星辰大阵——软件终端架构思维———未来之窗行业应用跨平台架构