全新揭秘:Java WebSocket全双工通信的实践与运用

news2025/7/9 0:20:49

全新揭秘:Java WebSocket全双工通信的实践与运用

    • 一、简介
      • 何为全双工通信全双工?
      • WebSocket的使用场景
    • 二、如何使用Java实现WebSocket
      • 1,引用websocket相关starter
      • 2,启用websocket
      • 3,服务端代码开发
      • 4,群发测试接口
      • 5,前端代码
    • 三、测试验证
    • 四、总结

一、简介

WebSocket是一种强大的跨平台和全双工通信的网络技术。它可以在客户端和服务器之间进行全双工通信,从而在真实的服务器推送场景中提供极好的性能和一致性。

何为全双工通信全双工?

全双工模式是指两端系统可以同时发送和接收信息,即客户端可以向服务端发起请求,并接收服务端的响应, 同时,服务端也可以主动向客户端发起请求,并接收客户端的响应。 而我们最常见的web应用,都属于请求-响应,属于半双工模式, 这种模式下,服务端是不能主动请求客户端的。
WebSocket提供了这种全双工通信方式,使得服务器可以随时把信息推送给客户端,客户端也能随时向服务器发送信息,减少了通信的延迟时间。

WebSocket的使用场景

这种全双工的通信方式,使得WebSocket在一些特殊场景下有着无比的优势:
1,实时应用:聊天室应用,多人协作的应用。
2,游戏应用:浏览器游戏或者手机app游戏等,他们需要在服务端和客户端之间保持低延迟、全双工和实时的数据交换。
3,实时展现:对于需要频繁更新的应用,WebSocket提供了一种高效的解决方案。
以及无需客户端提供公网IP,服务端即可以访问客户端的某些特殊场景(B2B场景下),比如服务端对接了多家银行,支付时又依赖于客户端插入的U盾。

二、如何使用Java实现WebSocket

Java EE7的APIs支持WebSocket协议,因此我们使用Java来实现WebSocket变得非常简单。以下以一个springboot web应用中,使用java WebSocket进行全双工通信示例:

1,引用websocket相关starter

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

2,启用websocket

在springboot启动类中,增加如下代码:

// 启用websocket
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

3,服务端代码开发

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.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * WebSocket测试服务
 */
@Component  // 也需要交于spring容器管理
@ServerEndpoint("/ws/{userId}")  // 服务地址
public class TestWebSocketServer {

    //长连接,即客户端会话对象
    private static Map<String, Session> clientMap = new HashMap();

    /**
     * 响应客户端socket open事件,接收客户端请求,建立连接
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        System.out.println("客户端:" + userId + "建立连接");
        clientMap.put(userId, session);
    }

    /**
     * 用来处理客户端发送消息事件,接收消息并处理
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") String userId) throws IOException {
        System.out.println("收到来自客户端:" + userId + "的信息:" + message);
        Session session = clientMap.get(userId);
        session.getBasicRemote().sendText(userId + " 你好,已收到你发送的消息:" + message);
    }

    /**
     * 响应客户端连接关闭事件调用的方法
     *
     * @param userId
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        System.out.println("连接断开:" + userId);
        clientMap.remove(userId);
    }

    /**
     * 测试群发消息,实现业务场景根据业务需要,发给特定的客户端,以实现客户端无刷新自动显示最新数据,比如下单被接单,客户催单提醒等。
     *
     * @param message
     */
    public void sendMessagesToALlUsers(String message) {
        Collection<Session> sessions = clientMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

4,群发测试接口

    @GetMapping("/ws/sendAll")
    public String sendToAllClients() {
        testWebSocketServer.sendMessagesToALlUsers("群发消息测试");
        return "success";
    }

5,前端代码

创建一个html页面,命名ws_demo.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 = "10000";  //  模拟的用户ID,实际业务场景可以用当前登录的用户的唯一标识

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

    //连接发生错误前端回调方法,比如服务端挂了
    websocket.onerror = function(){
        setMessageInnerHTML("与服务端连接出错");
    };

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

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("已关闭");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        closeWebSocket();
    }

    //将消息显示在网页上
    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>

三、测试验证

springboot后端应用启动:
在这里插入图片描述
打开前端页面
前端如果打开后,不能正常显示 ,可以将前端部署在nginx上,直接放到nginx的html目录下即可,然后通过浏览器访问http://localhost/ws_demo.html 即可显示页面如下。
在这里插入图片描述
在这里插入图片描述
客户端主动发送消息

在这里插入图片描述
服务端收到客户端响应
在这里插入图片描述
服务端主动向客户端群发测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
客户端断开(浏览器关闭)时,会触发onclose事件,服务端也会感知到; 同时服务端关闭时,也会触发服务端onclose事件,客户端也会被通知到,大家可以测试验证下。
以上测试展示了一个基于java websocket的全双工网络通信的具体示例,实现客户端和服务器之间进行全双工通信非常简便,在真实的服务器推送场景中只需扩展示例,实现具体的业务即可。

四、总结

总的来看,WebSocket带来了客户端和服务端通信的新可能,特别是在需要服务端主动推送消息给客户端的应用场景中,其出色的实时性和低延迟性提供了前所未有的用户体验。Java作为一门全能的编程语言,也为我们使用WebSocket提供了完善的工具。使用Java去实现WebSocket应用,在实时性、低延迟和全双工这些方面,将会非常高效。

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

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

相关文章

文献速递:生成对抗网络医学影像中的应用——基于CycleGAN的图像到图像转换,用于逼真的外科手术训练模型

文献速递&#xff1a;生成对抗网络医学影像中的应用——基于CycleGAN的图像到图像转换&#xff0c;用于逼真的外科手术训练模型 本周给大家分享文献的主题是生成对抗网络&#xff08;Generative adversarial networks, GANs&#xff09;在医学影像中的应用。文献的研究内容包括…

【3D】designdoll 人偶生图 入门到精通 //必看课程

二种方法&#xff0c;根据 desigon doll 生成图片 文生图&#xff1a;tilelineart 图生图&#xff1a;openposedepth best quality,masterpiece,8k,1 girl,flame,black stockings,blush,glasses,pantyhose,competition school swimsuit,magic circle, designdoll 下载模型 查找…

UE5 Landscape 制作GIS卫星图地形

1. 总体想法&#xff1a; 制作GIS地形&#xff0c;使用Landscaping MapBox是一个好方法&#xff0c;但是区域过大&#xff0c;会占用很多内存 https://blog.csdn.net/qq_17523181/article/details/135029614 如果采用QGis&#xff0c;导出卫星图&#xff0c;在UE5里拼合出地形…

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

文章目录 1、二叉搜索树1.1 二叉搜索数的概念1.2 二叉搜索树的操作1.2.1 二叉搜索树的查找1.2.2 二叉搜索树的插入1.2.3 二叉搜索树的删除 2、二叉搜索树的应用2.1 K模型2.2 KV模型 3、二叉搜索树的性能分析4、K模型与KV模型完整代码4.1 二叉搜索树的模拟实现&#xff08;K模型…

养老院自助饮水机(字符设备驱动)

目录 1、项目背景 2、驱动程序 2.1 三层架构 2.2 驱动三要素 2.3 字符设备驱动 2.3.1 驱动模块 2.3.2 应用层 3、设计实现 3.1 项目设计 3.2 项目实现 3.2.1 驱动模块代码 3.2.2 用户层代码 4、功能特性 5、技术分析 6. 总结与未来展望 1、项目背景 养老院的老人…

CSC访问学者/博士后/联培博士如何规划申请时间

申请国家留学基金委&#xff08;CSC&#xff09;公派访问学者/博士后/联合培养博士等出国项目&#xff0c;邀请函是必要条件&#xff0c;需提前准备。那么&#xff0c;何时提出申请比较合适&#xff1f;获得邀请函需要多长时间&#xff1f;根据知识人网多年的申请经验&#xff…

电影《名侦探柯南:黑铁的鱼影》观后感

上周看了电影《名侦探柯南&#xff1a;黑铁的鱼影》,整体故事的话,就是柯南他们团队一起去岛屿去上参观&#xff0c;“正好”碰上了“海上信标案件”&#xff0c;在柯南的电影里&#xff0c;用“正好”多少有些反讽的意味&#xff0c;因为柯南好像走到哪&#xff0c;都正好碰到…

Python实验报告十一、自定义类模拟三维向量及其运算

一、实验目的&#xff1a; 1、了解如何定义一个类。 2、了解如何定义类的私有数据成员和成员方法。 3、了解如何使用自定义类实例化对象。 二、实验内容&#xff1a; 定义一个三维向量类&#xff0c;并定义相应的特殊方法实现两个该类对象之间的加、减运算&#xff08;要…

Vue中为什么data属性是一个函数而不是一个对象?(看完就会了)

文章目录 一、实例和组件定义data的区别二、组件data定义函数与对象的区别三、原理分析四、结论 一、实例和组件定义data的区别 vue实例的时候定义data属性既可以是一个对象&#xff0c;也可以是一个函数 const app new Vue({el:"#app",// 对象格式data:{foo:&quo…

优化企业员工管理的利器——ADManager Plus

在当今数字化的商业环境中&#xff0c;企业员工管理是组织成功运营的关键组成部分。为了提高效率、确保安全性和满足法规合规性要求&#xff0c;企业需要一种强大的工具来简化和集中管理其活跃目录&#xff08;Active Directory&#xff09;环境。ADManager Plus作为一款功能丰…

利用ffmpeg cv2取h265码流视频(转换图片灰屏问题解决)

利用海康威视相机拍出来的视频是H265格式的&#xff0c;相比于常规的H264编码&#xff0c;压缩率更高&#xff0c;但因此如果直接用正常取流方法读取&#xff0c;会出现无法读取的情况 1. 如图h265码流取出图片为灰屏 2 、解决灰屏问题 import subprocess import cv2# 将h265流…

天津web前端就业培训班,Web机构选择重点

Web前端培训是目前非常热门的培训领域之一。很多领域都会涉及到web前端开发&#xff0c;比如传统互联网、房地产、金融、游戏、影视传媒等行业都需要web前端技术的支持。越来越多的企业和个人也需要建立自己的网站和移动应用程序&#xff0c;因此市场对web前端工程师的需求是非…

RabbitMQ笔记(基础篇)

RabbitMQ笔记_基础篇 MQ基本概念1. MQ概述2. MQ的优势和劣势2.1 优势☆2.2 劣势2.3 使用 MQ 需要满足什么条件呢&#xff1f; 3. 常见的MQ产品 RabbitMQ基本介绍1. RabbitMQ 基础架构2. RabbitMQ 中的相关概念3. RabbitMQ的6 种工作模式☆4. AMQP 和 JMS4.1 AMQP4.2 JMS4.3 AMQ…

文件夹数据同步工具 Sync Folders Pro mac支持选项

Sync Folders Pro for Mac 是一款功能强大的文件夹同步工具&#xff0c;旨在帮助用户在 Mac 计算机和移动设备之间创建双向同步。这款软件支持各种文件系统和设备&#xff0c;如 iPhone&#xff0c;iPad&#xff0c;iPod&#xff0c;Android 等。通过这款软件&#xff0c;用户可…

[c]超半的数

题目意思很简单&#xff0c;就是输入一组数据&#xff0c;输出出现次数过半的数 根据这个题我们也可以写出另一个题&#xff0c;&#xff08;题2&#xff09;&#xff08;统计一组数据中各个数出现的次数&#xff09; 下面附上两个题代码 题1&#xff1a; #include<stdio.…

【C语言】自定义类型:结构体深入解析(二)结构体内存对齐宏offsetof计算偏移量结构体传参

文章目录 &#x1f4dd;前言&#x1f320; 结构体内存对齐&#x1f309;内存对齐包含结构体的计算&#x1f320;宏offsetof计算偏移量&#x1f309;为什么存在内存对⻬?&#x1f320; 结构体传参&#x1f6a9;总结 &#x1f4dd;前言 本小节&#xff0c;我们学习结构的内存对…

什么是网络工程师? 就业前景好吗?

互联网发展日渐成熟&#xff0c;所有企业都依赖于网络管理&#xff0c;有企业的地方就需要网络工程师。 在一般人的概念里&#xff0c;网络工程师不过就是通过拨号上网&#xff0c;发个Email&#xff0c;聊聊天&#xff0c;计算机组装与维护&#xff0c;组建局域网就以为是网络…

项目进度管理:常用项目管理工具推荐

工欲善其事必先利其器&#xff0c;借助项目管理工具可以帮助项目经理更好的管理项目&#xff0c;起到事半功倍的效果。 使用项目管理工具来管理项目&#xff0c;有助于事情的快速落地&#xff0c;提升做事效率&#xff0c;也能让事情做的更周到全面 选择项目管理工具时可以参…

uniapp、微信小程序类似mui中的chat(聊天窗口)

在mui中有chat界面的例子&#xff0c;升级到uni-app后&#xff0c;没有类似的模板&#xff0c;因此模仿写了一个。遇到了一些坑&#xff0c;在此一一记录下来。当然&#xff0c;由于是新手&#xff0c;可能有些坑可以避开。 预览效果 scroll-view高度的设置 输入内容后&#…

室内导航技术在智慧医疗的革新应用

随着科技的飞速发展&#xff0c;智慧医疗已经成为现代医疗服务的重要组成部分。在这个背景下&#xff0c;室内导航技术逐渐崭露头角&#xff0c;为智慧医疗建设带来了革命性的改变。本文将深入探讨室内导航技术在智慧医疗中的应用&#xff0c;并分析其为医疗服务带来的诸多便利…