java网络通信:Springboot整合Websocket

网络通信

  • 什么是webSocket?
  • WebSocket 原理
  • springboot整合websocket过程

网络通信三要素:ip地址(ipv4、ipv6)、端口号(应用程序的唯一标识)、协议(连接和通信的规则,常用:tcp、udp)

小区-房屋-道路
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Socket 是 “套接字” 的缩写,它用于在计算机之间建立通信链接,允许数据在这些连接上进行传输。

什么是webSocket?

WebSocket(Web套接字)是一种在单个 TCP 连接上实现全双工通信的协议,允许客户端和服务器之间进行双向实时通信。WebSocket 是 HTML5 标准的一部分,其主要特点包括:

  1. 双向通信: WebSocket 允许服务器向客户端主动推送消息,同时也允许客户端发送消息给服务器,实现了双向通信。
  2. 持久连接: 与传统的 HTTP 请求-响应模型不同,WebSocket 连接在建立后可以一直保持,而不需要为每个消息都建立新的连接,减少了通信的延迟和开销。
  3. 低延迟: WebSocket 具有较低的通信延迟,适用于需要实时性的应用,如在线聊天、实时数据监控、在线游戏等。
  4. 跨域支持: WebSocket 支持跨域通信,可以在不同域名的服务器之间建立连接。
  5. 轻量级头部: WebSocket 协议的头部数据较小,减少了通信开销。

WebSocket 原理

WebSocket 协议建立在 HTTP 协议之上,通过 HTTP 请求的升级机制(Upgrade)来升级为 WebSocket 连接。基本的连接过程如下:
客户端发起 WebSocket 连接请求,与服务器建立 TCP 连接

服务器响应 WebSocket 握手请求,双方达成协议升级,完成连接建立。

建立连接后,客户端和服务器可以通过 WebSocket 消息进行双向通信。

连接可以一直保持开启,直到其中一方发送关闭连接请求。

WebSocket 连接是一个持久连接,使用固定的套接字地址(ws:// 或 wss://)和端口号(通常是 80 或 443)。WebSocket 消息使用一种轻量级的帧格式,减少了通信开销。这使得 WebSocket 适用于需要实时通信的应用,如在线聊天、实时数据更新、在线游戏等。

在 Java 中,WebSocket 库通常会处理 WebSocket 握手、消息编码和解码、连接管理等底层细节,开发者可以专注于应用层的逻辑。WebSocket 协议的双向通信模型使其成为实时通信应用的理想选择,它在实时性要求高的场景中有广泛的应用。

springboot整合websocket过程

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version> <!-- 使用正确的版本号 -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springws</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springws</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>8</java.version>
    </properties>

基本依赖

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>5.3.12</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-websocket</artifactId>
            <version>9.0.55</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

系统配置

server.port=8080
# WebSocket
websocket.address=ws://localhost:8080

配置文件

@Configuration
public class WebSocketConfig {

    @Value("${ws://localhost:8080}")
    private String websocketAddress;

    /**
     * 注入ServerEndpointExporter,
     * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

Wbsocket操作类

在这里插入图片描述

package com.hs.websocket;

import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")  // 接口路径 ws://localhost:8087/webSocket/userId;
public class WebSocket {

    private Session session;
    private String userId;
    private static Map<String, Session> sessionPool = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        sessionPool.put(userId, session);
        log.info("&#8203;``【oaicite:3】``&#8203;有新的连接,总数为: {}", sessionPool.size());
    }

    @OnClose
    public void onClose() {
        sessionPool.remove(userId);
        log.info("&#8203;``【oaicite:2】``&#8203;连接断开,总数为: {}", sessionPool.size());
    }

    @OnMessage
    public void onMessage(String messageText) {
        log.info("&#8203;``【oaicite:1】``&#8203;收到客户端消息: {}", messageText);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误, 原因: {}", error.getMessage());
    }

    public void sendAllMessage(String message) {
        log.info("&#8203;``【oaicite:0】``&#8203;广播消息: {}", message);
        sessionPool.values().forEach(this::sendMessage);
    }

    public void sendOneMessage(String targetUserId, String message) {
        Session session = sessionPool.get(targetUserId);
        if (session != null && session.isOpen()) {
            sendMessage(session, message);
        }
    }

    public void sendMoreMessage(String[] targetUserIds, String message) {
        for (String targetUserId : targetUserIds) {
            Session session = sessionPool.get(targetUserId);
            if (session != null && session.isOpen()) {
                sendMessage(session, message);
            }
        }
    }

    private void sendMessage(Session targetSession, String message) {
        try {
            targetSession.getAsyncRemote().sendText(message);
        } catch (IOException e) {
            log.error("发送消息失败: {}", e.getMessage());
        }
    }
}

前端测试

<!DOCTYPE HTML>
<html>
<head>
    <title>Test My WebSocket</title>
</head>


<body>
TestWebSocket
<input id="text" type="text"/>
<button onclick="send()">SEND MESSAGE</button>
<button onclick="closeWebSocket()">CLOSE</button>
<div id="message"></div>
</body>

<script type="text/javascript">
    var websocket = null;


    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        //连接WebSocket节点
        websocket = new WebSocket("ws://localhost:8080/websocket/88");
    } else {
        alert('Not support websocket')
    }


    //连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("error");
    };


    //连接成功建立的回调方法
    websocket.onopen = function (event) {
        setMessageInnerHTML("open");
    }


    //接收到消息的回调方法
    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 closeWebSocket() {
        websocket.close();
    }


    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

postman测试

创建新的workspaces

通过ctrl+n进入
在这里插入图片描述

基于以下url进行联通测试

ws://localhost:8080/websocket/88

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于袋獾算法的无人机航迹规划-附代码

基于袋獾算法的无人机航迹规划 文章目录 基于袋獾算法的无人机航迹规划1.袋獾搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用袋獾算法来优化无人机航迹规划。 1.袋獾搜索算法 …

深入探讨 Presto 中的缓存

Presto是一种流行的开源分布式SQL引擎&#xff0c;使组织能够在多个数据源上大规模运行交互式分析查询。缓存是一种典型的提高 Presto 查询性能的优化技术。它为 Presto 平台提供了显着的性能和效率改进。 缓存通过将频繁访问的数据存储在内存或快速本地存储中&#xff0c;避免…

redis的数据类型及操作

一、redis 的数据库 Redis是一个字典结构的存储服务器。一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存在哪个字典中。这与关系型数据库例中可以创建多个数据库似。因此,可以将每个字典理解为一个独立的数据库。每个数据库对外都是以0开始的递增数字命名…

HTML的表单标签和无语义标签的讲解

HTML的表单标签 表单是让用户输入信息的重要途径, 分成两个部分: 表单域: 包含表单元素的区域. 重点是 form 标签. 表单控件: 输入框, 提交按钮等. 重点是 input 标签 form 标签 使用form进行前后端交互.把页面上,用户进行的操作/输入提交到服务器上 input 标签 有很多形态,能…

本地消息表分布式事务

BASE论文 论文链接&#xff1a;https://queue.acm.org/detail.cfm?id1394128 里面提到&#xff0c; The most critical factor in implementing the queue, however, is ensuring that the backing persistence is on the same resource as the database. This is necessary…

5G边缘计算网关的功能及作用

5G边缘计算网关具有多种功能。 首先&#xff0c;它支持智能云端控制&#xff0c;可以通过5G/4G/WIFI等无线网络将采集的数据直接上云&#xff0c;实现异地远程监测控制、预警通知、报告推送和设备连接等工作。 其次&#xff0c;5G边缘计算网关可以采集各种数据&#xff0c;包…

vue中 process.env 对象为空对象问题

问题&#xff1a;今天在处理vue项目环境问题的时候&#xff0c;发现直接打印 process 对象和打印 process.env 时 env 对象输出结果是不一样的&#xff0c;如下图所示&#xff1a; 在网上搜索了一番后发现还是有挺多朋友对此感到疑惑的&#xff0c;询问了同事&#xff0c;同…

数模之线性规划

线性规划 优化类问题&#xff1a;有限的资源&#xff0c;最大的收益 例子: 华强去水果摊找茬&#xff0c;水果摊上共3个瓜&#xff0c;华强总共有40点体力值,每劈一个瓜能带来40点挑衅值,每挑一个瓜问“你这瓜保熟吗”能带来30点挑衅值,劈瓜消耗20点体力值&#xff0c;问话消耗…

Vue3 简单实现虚拟Table,展示海量单词.利用WebAPI speechSynthesis,朗读英语单词

目录 本页面完整代码 视频演示 完整的页面代码 利用webapi speechSynthesis帮助我们自动郎读英语单词&#xff0c;可以利用这个API&#xff0c;做一些小说朗读或到账提示。 本页面完整代码 用Vue写了一个简单页面&#xff0c;里面还写了一个简单的虚拟Table支持海量数据展示…

ubuntu 18.04安装自己ko驱动 修改secure boot

因为本人老折腾自己的电脑&#xff0c;所以老重装系统&#xff0c;然后配置又不见了&#xff0c;这次配置赶紧记下来 insmod netlink_test.ko 报错&#xff1a;insmod: ERROR: could not insert module netlink_test.ko: Operation not permitted 添加 sudo insmod netlink_te…

XCTF刷题十一道(01)

文章目录 Training-WWW-RobotsPHP2unserialize3view-sourceget_postrobotsbackupcookiedisabled_buttonweak_authsimple_php Training-WWW-Robots robots.txt&#xff0c;防爬虫&#xff0c;访问urlrobots.txt PHP2 phps源码泄露 >phps文件就是php的源代码文件&#xff0…

swift语言用哪种库适合做爬虫?

目录 1、Alamofire 2、URLSession 3、YepHttp 4、Kickbox 5、Vapor 注意事项 总结 在Swift语言中&#xff0c;可以使用第三方库来帮助进行网络爬虫的开发。以下是几个适合Swift语言使用的爬虫库&#xff0c;以及相应的代码示例&#xff1a; 1、Alamofire Alamofire是Sw…

【k8s】pod控制器

一、pod控制器及其功用 Pod是kubernetes的最小管理单元&#xff0c;在kubernetes中&#xff0c;按照Pod的创建方式可以将其分为两类 自主式Pod&#xff1a; kubernetes直接创建出来的Pod&#xff0c;这种Pod删除后就没有了&#xff0c;也不会重建 控制器创建的Pod&#xff1a…

润和软件HopeStage与奇安信网神终端安全管理系统、可信浏览器完成产品兼容性互认证

近日&#xff0c;江苏润和软件股份有限公司&#xff08;以下简称“润和软件”&#xff09;HopeStage 操作系统与奇安信网神信息技术&#xff08;北京&#xff09;股份有限公司&#xff08;以下简称“奇安信”&#xff09;终端安全管理系统、可信浏览器完成产品兼容性测试。 测试…

多路转接(上)——select

目录 一、select接口 1.认识select系统调用 2.对各个参数的认识 二、编写select服务器 1.两个工具类 2.网络套接字封装 3.服务器类编写 4.源文件编写 5.运行 一、select接口 1.认识select系统调用 int select(int nfds, fd_set readfds, fd_set writefds, fd_set ex…

Node.js |(六)express框架 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;express使用&#x1f407;初体验&#x1f407;express路由⭐️路由的使用⭐️获取请求参数⭐️获取路由参数&#x1f525;练习&#xff1a;根据路由参数响应歌手信息…

小白学爬虫:通过关键词搜索1688商品列表数据接口|1688商品列表数据接口|1688商品列表数据采集|1688API接口

通过关键词搜索1688商品列表数据接口可以使用1688开放平台提供的API接口实现。以下是使用关键词搜索商品列表数据的基本步骤&#xff1a; 1、注册并获取AppKey。 2、构造请求参数&#xff0c;包括搜索关键词、页码、每页条数等。 3、通过API接口链接&#xff0c;将请求参数发送…

简单漂亮的登录页面

效果图 说明 开发环境&#xff1a;vue3&#xff0c;sass 代码 <template><div class"container"><div class"card-container"><div class"card-left"><span><h1>Dashboard</h1><p>Lorem ip…

后台管理系统解决方案-中大型-Vben Admin

后台管理系统解决方案-中大型-Vben Admin 官网 Vben Admin 在线演示 Vben Admin 为什么选择它 github现有20K星&#xff0c;并且它有个可视化生成表单&#xff0c;我很喜欢 快速开始 # 拉取代码 git clone https://github.com/vbenjs/vue-vben-admin-doc# 安装依赖 yarn#…

【ONE·C++ || 网络基础(二)】

总言 主要内容&#xff1a;演示socke套接字编程&#xff08;TCP模式&#xff09;&#xff0c;介绍序列化和反序列化&#xff0c;并进行演示&#xff08;json版本达成协议编写、守护进程介绍&#xff09;。 文章目录 总言4、基于套接字的TCP网络程序4.0、log.hpp4.1、version1.…