一文了解websocket全双工通信java实现&socket地址404问题解决

2023-10-26

1.websocket介绍

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

1.1注解介绍

@ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。
注解的值将被用于监听用户连接的终端访问URL地址。
@OnMessage 前端发送消息 进行处理
@OnClose  关闭处理
@OnOpen  前端打开页面的处理

2.demo

引入依赖:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.5.5'

2.1 后端代码

package com.zqm.utils.socket;

/**
 * @describe: sid 需要提前约定
 * @author:zqm
 */

import org.apache.commons.lang3.StringUtils;
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.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketTest {

    private static final ConcurrentHashMap<String, Session> SESSION_MAP = new ConcurrentHashMap();

    /**
     * 接受消息
     * @param sid
     * @param session
     * @throws IOException
     * @throws InterruptedException

    //    @OnMessage
    //    public void onMessage(@PathVariable("sid") String sid, Session session)
    //            throws IOException, InterruptedException {
    //        System.out.println();
    //    }
     */

    /**
     * 接受消息
     *
     * @param message 客户端发送的消息
     * @param session
     * @throws IOException
     * @throws InterruptedException
     */

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println(session.getPathParameters().get("sid"));
        System.out.println(message);
    }

    /**
     * 登记连接
     *
     * @param sid
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("sid") String sid, Session session) {
        if (SESSION_MAP.containsKey(sid)) {
            return;
        }
        SESSION_MAP.put(sid, session);
        System.out.println("Client connected");
    }


    /**
     * 注销连接
     */
   c
    public void onClose() {
        System.out.println("Connection closed");
    }


    public void sendMessage(String sid, String message) throws IOException {
        if (StringUtils.isNotBlank(sid)) {
            Session session = SESSION_MAP.get(sid);
            session.getBasicRemote().sendText(message);
        }

    }
}


package com.zqm.controller;

import com.zqm.utils.socket.WebSocketTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * @describe:
 * @author:zqm
 */
@RestController
@RequestMapping("web-socket")
public class WebSocketController {

    @Autowired
    private WebSocketTest webSocketTest;

    @RequestMapping("send")
    public void sendMessage(String message) throws IOException {
        webSocketTest.sendMessage("user000",message);
    }
}

2.2 前端代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        Websocket Demo <br />
        <input id="text" type="text" /> 
        <button onclick="send()"> Send </button>   
        <button   onclick="closeWebSocket()"> Close </button>
        <div id="message">   </div>
        
    <script type="text/javascript">
     //判断当前浏览器是否支持WebSocket
      if('WebSocket' in window){
          websocket = new WebSocket("ws://192.168.43.12:8081/zqm/websocket/user");
          console.log("link success")
      }else{
          alert('Not support websocket')
      }
      
      //连接发生错误的回调方法
      websocket.onerror = function(){
          setMessageInnerHTML("error");
      };
       
      //连接成功建立的回调方法
      websocket.onopen = function(event){
          setMessageInnerHTML("open");
      }
       console.log("-----")
      //接收到消息的回调方法
      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>
        
    </body>
</html>

2.3 效果

1.先启动后端服务,打开html,显示连接成功
在这里插入图片描述
2.客户端发送消息,后台接受成功
在这里插入图片描述

3.后台发送消息,客户端接受成功
在这里插入图片描述

附录:socket地址404问题解决

@Configuration
@EnableWebSocket
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpoint() {
        return new ServerEndpointExporter();
    }
}
或者
@Configuration
public class WebSocketConfig extends ServerEndpointConfig.Configurator{

    @Bean
    public ServerEndpointExporter serverEndpoint() {
        return new ServerEndpointExporter();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文了解websocket全双工通信java实现&socket地址404问题解决 的相关文章

  • android 录音时可以静音吗

    我想构建一个应用程序 我想在通话中调制声音 我编写了一段代码来记录声音并以不同的音调播放它 现在我想要在通话时使用此功能 我想将通话静音 记录声音然后以不同的音调播放它 如何将通话静音但仍录制音频 此答案可在通话期间使麦克风静音 Boole
  • 一次向字符串添加一行

    我有这个程序 可以让你打开一个文件并将其读入一个JTextArea使用以下代码一次性完成所有操作 try String fileContents new Scanner new File fileName useDelimiter Z ne
  • Websocket 连接失败并显示星号 11

    我正在尝试将 websocket 配置为与 asterisk 11 一起使用 但是存在一些问题 我遵循的步骤是 在 http conf 中启用以下内容 enabled yes bindaddr 0 0 0 0 bindport 8088 我
  • 如何在Spring中模拟ModelMapper?

    我正在尝试为我的服务层编写单元测试 SpringBootTest class ClinicServiceTest Mock private ProcedureRepository procedureRepository InjectMock
  • 生成总和为 N 的所有数字排列

    我正在编写一个程序来创建所有数字 起初 我尝试使用分区函数对数字进行分区 然后对每个数字集进行排列 但是我认为这行不通 最好的方法是递归排列 同时对数字求和 这超出了我的能力范围 抱歉 如果这听起来真的很愚蠢 但我真的不知道 Example
  • 在 Java 中引发竞争条件

    我必须编写一个引发竞争条件的单元测试 以便我可以测试稍后是否可以解决问题 问题是竞争条件很少发生 可能是因为我的计算机只有两个核心 代码如下 class MyDateTime String getColonTime datetime is
  • 使用服务器帐户模拟用户以访问其 Google 云端硬盘时出现 401 未经授权错误

    我正在用 Java 编写一个后端进程 它将模拟用户并在其 Google Drive 上添加 删除文档 服务器帐户似乎验证正确 但是当我尝试冒充用户时 我得到一个401 Unauthorized error 请参阅下面的详细信息 配置 我已配
  • 一个好的 Java VM 中方法调用的开销是多少?

    有人可以提供反汇编的机器代码汇编程序列表吗 我的意思是 与 C 中的普通函数调用相比 肯定有一些开销 VM 需要跟踪调用以查找热点 并且当它使用编译代码时 如果新加载的类需要重新编译 它需要提供动态更改编译方法的方法 我想某处也有返回堆栈溢
  • Java 按日期作为字符串对列表 进行排序

    我有一个类型列表 我想按日期元素对该列表进行排序 我用谷歌搜索 看到了一些具有可比性的解决方案 但是是否有可能在不实现类中接口的情况下做到这一点 我的列表如下所示 列表 id 33 文本 test1 日期 06 02 15 id 81 文本
  • itext更改所有超链接的缩放级别以继承现有pdf中的缩放

    我正在使用以下代码将所有超链接的缩放级别更改为继承缩放 但无法改变 可能我在 PdfName DEST 和条件中犯了一些错误 因为第一页的 pdf 中没有 DEST 数组 查看屏幕截图 for int count 0 count lt re
  • 尽管 CRC 错误,仍强制 gzip 解压缩

    我认为有办法做到这一点 但我不确定如何做 基本上 我正在编写一个压缩程序 当我尝试解压缩压缩数据时 该程序导致了 crc 错误 通常 这意味着解压缩器实际上将我的数据识别为正确的格式并将其解压缩 但是当它将结果与 CRC 指示的预期长度进行
  • Jsoup遍历DOM树时节点哈希码冲突

    我正在使用 java jsoup 构建 HTML DOM 树 其中Node hashCode 用来 但我发现在遍历DOM树时存在很多哈希码冲突 使用以下代码 doc traverse new NodeVisitor Override pub
  • JSP 通常是作为 .jsp 文件、预编译的 Java 文件还是预编译的类文件提供的?

    在为生产环境准备 WAR 时 是否有打包 JSP 的 标准 实践 它们是否包含为 jsp 文件 或者它们是否作为预编译的 Java 文件或预编译的类文件包含在内 Servelts JSP 规范没有提及预编译 JSP 来实现此功能具体到容器实
  • 尝试让 GUI 使用 arrayList 在牌组中打印随机卡

    所以我目前正在用java开发一个卡牌战争游戏 我试图让 GUI 屏幕使用 arrayList 从一组卡片图像中打印 2 张随机卡片 必须使用它进行分配 卡片图像文件名为 1 png 2 png 52 png 并存储在 image card
  • Tomcat 连接池与准备好的语句缓存

    从 DBCP 连接池升级到 Tomcat 自己的实现 基于优秀的比较here http tomcat apache org tomcat 7 0 doc jdbc pool html Introduction 我有点困惑为什么他们放弃了这两
  • Android:如何管理同一应用程序使用的多个库中的公共代码库

    NOTE 这个问题是基于我在以下讨论中收到的答案 Android 2个具有相同包的aar库 https stackoverflow com questions 57347039 android 2 aar libraries with th
  • ConcurrentLinkedDeque 与 LinkedBlockingDeque

    我需要一个线程安全的 LIFO 结构 并发现我可以使用线程安全的实现Deque为了这 Java 7 引入了ConcurrentLinkedDeque http docs oracle com javase 7 docs api java u
  • 如何修复 Jaspersoft studio 插件中由 TraceGovernor 引起的 java.lang.NullPointerException?

    我正在为 Jaspersoft studio 编写最新的插件 当尝试打开报告预览时 插件崩溃 来自插件 java lang NullPointerException 的堆栈跟踪 com jaspersoft studio debug Tra
  • 如何通过代码使用 Google 翻译 API

    我正在尝试创建一个可以发送单词的应用程序翻译 google com 获取翻译结果并将其显示给用户 我编写了 URL 但我不知道如何从网页中提取单词 短语 伪示例 en 是英语代码 es 是西班牙语代码 String from en Stri
  • 带有 wsdl2java 插件的 gradle

    我正在使用 no nils wsdl2java 插件 完整的 gradle build 文件如下所示 plugins id org springframework boot version 2 3 4 RELEASE id io sprin

随机推荐

  • 点云数据下的KD-tree

    点云数据下的KD tree检索 数据结构 构建KD tree 最近邻检索 KD tree简称K维树 是一种空间划分的数据结构 常被用于高维空间中的搜索 比如范围搜索和最近邻搜索 kd tree是二进制空间划分树的一种特殊情况 在激光雷达SL
  • go mod vender package io/fs is not in GOROOT (/usr/local/go/src/io/fs)

    一 问题解决 最近写区块链相关项目时候 对于智能合约部署时对其进行vender时报错 io fs is not in GOROOT usr local go src io fs 搜索了一下是因为go版本问题 我原本是1 15 5的版本 后来
  • 实施MES系统有何难点,以及怎么解决?

    实施MES系统有何难点 以及怎么解决 很多制造企业当前对于MES系统还处于认知阶段 制造业管理者们在不断了解MES系统的过程中 发现实施MES并没有想象中的简单 一个成熟的MES系统要经历哪些难点 如何更好的解决 一 MES系统有哪些实施难
  • Docker之DockerFile相关基础知识

    DockerFile相关基础知识 一 Docker镜像原理 1 操作系统组成部分 1 1 七大子系统 1 2 Linux文件系统 2 Docker镜像原理介绍 2 1 原理图 2 2 Docker镜像本质 2 3 统一文件系统 2 4 复用
  • react配置项目路径别名@

    为什么有的项目引入路径写 可以 自己的不行呢 因为别人的项目是配置过路径别名的 就表示src目录 因此我们也需要配置一遍 以下是react项目示范 vue项目同理 ts对 指向src目录的提示是不支持的 vite默认也不支持 所以需要手动配
  • 如何计算TCP吞吐量

    为什么80 的码农都做不了架构师 gt gt gt FROM how to calculate tcp throughput for long distance links 如何计算广域网链路的 TCP 吞吐量 刚刚点亮数据中心之间的高速网
  • Linux IP出现inet6 addr :fe80::20c:29ff:fe47:fd61/64 scope:l

    经常出现 inet6 addr fe80 20c 29ff fe47 fd61 64 scope link1 这种情况的不要担心了 试试这个方法 这也是我折磨了好多天整理的 不喜勿喷 谢谢 虚拟机设置权限 sudo chown book b
  • Git学习笔记

    配置user信息 配置user name git config global user name your name 配置user email git config global user email your email 查看所有配置信息
  • Jenkins中连接Git仓库时提示:无法连接仓库:Error performing git command: git ls-remote -h

    问题 Jenkins中连接Git仓库时提示 无法连接仓库 Error performing git command git ls remote h 原因 git的账号密码错误 解决方案 重新设置账号密码 操作 控制面板 凭证管理器 wind
  • 有趣的异常

    缘起 最近 在项目中遇到一个有趣的异常 在没附加调试器的情况下会直接崩溃 附加调试器后 会中断到调试器中 但是按 F5 继续运行后 程序还能继续执行 interesting 你能猜出这是个什么异常吗 初遇错误 在测试程序功能的时候 意外的崩
  • 【教程】一款Markdown 编辑器,免费版本 Typora 下载与使用.

    csdn资源老挂 再补一个网盘的 哪个能用用哪个吧 链接 https pan baidu com s 19c MJQRuas9v5lHxF1uB6A pwd f3n5 提取码 f3n5 gt gt 资源 lt
  • EXCEL-数据透视表、日数据整理成月数据

    1 当你面对一个很多年的日数据 想要把它整理成月数据 下图是2015年1月到2022年1月的日数据 2 首先我们把没用的信息挪开 在时间和日数据上加个表头 3 接着选中数据 包括表头 点击 插入 数据透视表 4 跳出来的框框 直接确认 5
  • AppsFlyer 研究(四)OneLink Deep Linking Guide

    一 简介 深度链接是指当用户打开移动应用时向其提供个性化的内容 或将用户带到应用内特定位置的操作 通过这种操作 您可以为用户提供优质的用户体验 从而极大加强用户与应用的互动 两种深度链接类型 由于用户不一定安装了移动应用 所以有两种深度链接
  • 曾经被视为「牛市制造机」们的机构巨鲸,如今都怎么了?

    这是白话区块链的第1790期原创 作者 Terry出品 白话区块链 ID hellobtc 11 月 17 日 萨尔瓦多总统 Nayib Bukele 表示 从明天开始 我们将每天购买一个比特币 直接开始了国家级别的比特币定投之旅 相信不少
  • 【图片二值化处理,以及byte[] 与bitmap互相转化问题】

    1 byte与bitmap相互转换 将byte流转换为bitmap byte signature item ToArray MemoryStream ms1 new MemoryStream signature Bitmap bm Bitm
  • 打开ABAQUS时,显示找不到 MFC140U.DLL 文件,打不开软件,亲测解决

    打开ABAQUS时 显示找不到 MFC140U DLL 文件 打不开软件 如何解决 下载了X64版本的 安装完毕后就可以打开了 Microsoft Visual C 2017 Redistributable 32位链接 link 64位链接
  • 时钟同步-注意客户端和服务端都需要开启123端口 udp协议

    确认时钟源 chronyc sources v chronyc tracking Linux Chronyd时间同步服务器详解 wangjie722703的博客 CSDN博客 local stratum 10 即使自己未能通过网络时间服务器
  • pytorch-lightning如何设置训练epoch

    Trainer初始化时添加max epochs参数 init model autoencoder LitAutoEncoder trainer pl Trainer gpus 8 max epochs 50 trainer fit auto
  • iOS uiscrollView 嵌套 问题 的解决

    苹果官方文档里面提过 最好不要嵌套scrollView 特别提过UITableView和UIWebView 因为在滑动时 无法知道到底是希望superScrollView滑动还是subScrollView滑动 一旦出现这种情况 情况就出乎我
  • 一文了解websocket全双工通信java实现&socket地址404问题解决

    websocket介绍 1 websocket介绍 1 1注解介绍 2 demo 2 1 后端代码 2 2 前端代码 2 3 效果 附录 socket地址404问题解决 1 websocket介绍 WebSocket是一种在单个TCP连接上