Java开发-WebSocket

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信-浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并实现 双向数据传输。

使用

导入maven坐标

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

前端页面

<!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 = Math.random().toString(36).substr(2);//判断当前浏览器是否支持WebSocketif('WebSocket' in window){//连接WebSocket节点websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);}else{alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function(){setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(){setMessageInnerHTML("连接成功");}//接收到消息的回调方法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 send(){var message = document.getElementById('text').value;websocket.send(message);}//关闭连接function closeWebSocket() {websocket.close();}
</script>
</html>

后端Server

 package com.sky.websocket;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.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}/*** 连接关闭调用的方法** @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}/*** 群发** @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

编写配置类

package com.sky.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类,用于注册WebSocket的Bean*/
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

定时任务类

package com.sky.task;import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5秒向客户端发送消息*/@Scheduled(cron = "0/5 * * * * ?")public void sendMessageToClient() {webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}
}

测试成功:

image-20231025225532485

public void onActivityResult(ActivityResult result) {if (result != null) {Intent data = result.getData();if (data != null && result.getResultCode() == RESULT_OK) {boolean isCheated = data.getBooleanExtra(CheatActivity.IS_CHEATED, false);if (isCheated) {Toast.makeText(getApplicationContext(), "使用答案提示", LENGTH_SHORT).show();} else {Toast.makeText(getApplicationContext(), "没有使用答案提示", LENGTH_SHORT).show();}} else {Toast.makeText(getApplicationContext(), "从CheatAcitivity返回", LENGTH_SHORT).show();}}
}

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

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

相关文章

基于V/F控制的三相逆变器MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 参考文献&#xff1a;张飞,刘亚,张玉杰.基于V/F控制的三相逆变器仿真模型的研究[J].自动化与仪器仪表,2015 关于V/F控制的论文非常多&#xff0c;随意下载&#xff01; 当分布式电源经过逆变器运行于孤岛模…

【计算机毕设案例推荐】高校学术研讨信息管理系统小程序SpringBoot+Vue+小程序

前言&#xff1a;我是IT源码社&#xff0c;从事计算机开发行业数年&#xff0c;专注Java领域&#xff0c;专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务 项目名 基于SpringBoot的高校学术研讨信息管理系统小程序 技术栈 SpringBoot小程序VueMySQLMaven 文…

UE4 材质实操记录

TexCoord的R通道是从左到右的递增量&#xff0c;G通道是从上到下的递增量&#xff0c;R通道减去0.5&#xff0c;那么左边就是【-0.5~0】区间&#xff0c;所以左边为全黑&#xff0c;Abs取绝对值&#xff0c;就达到一个两边向中间的一个递减的效果&#xff0c;G通道同理&#xf…

stm32外部时钟为12MHZ,修改代码适配

代码默认是8MHZ的&#xff0c;修改2个地方&#xff1a; 第一个地方是这个文件的这里&#xff1a; 第二个地方是找到这个函数&#xff1a; 修改第二个地方的这里&#xff1a;

javaEE -5(8000字详解多线程)

一&#xff1a;JUC(java.util.concurrent) 的常见类 1.1 ReentrantLock 可重入互斥锁. 和 synchronized 定位类似, 都是用来实现互斥效果, 保证线程安全&#xff0c;ReentrantLock 也是可重入锁. “Reentrant” 这个单词的原意就是 “可重入” ReentrantLock 的用法&#xf…

TypeScript学习 | 泛型

简介 泛型是指在定义函数、接口或类的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性 作用 可以保证类型安全的前提下&#xff0c;让函数、接口或类与多种类型一起工作&#xff0c;从而实现复用 基本使用 举个例子&#xff1a; 创…

T113-S3-buildroot文件系统tar解压缩gz文件

目录 前言 一、现象描述 二、解决方案 三、tar解压缩.gz文件 总结 前言 本文主要介绍全志T113-S3平台官方SDK&#xff0c;buildroot文件系统tar不支持.gz文件解压缩的问题以及如何配置buildroot文件系统解决该问题的方法介绍。 一、现象描述 在buildroot文件系统中&#xff…

二、可行性分析与需求分析

文章目录 概念考点练习题一、可行性分析与需求分析1.可行性分析的任务2.可行性研究3.甘特图4.数据流图5.数据字典数据字典的内容 6.需求分析7. 实体联系ER图8. 状态转换图 二、练习题 概念考点练习题 一、可行性分析与需求分析 1.可行性分析的任务 用最小的代价在尽可能短的时…

【德哥说库系列】-PostgreSQL跨版本升级

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

区块链外包开发需要注意的问题

在进行区块链外包开发时&#xff0c;有一些关键问题需要特别注意&#xff0c;以确保项目的成功和质量。以下是一些需要考虑的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.明确的需求和目标&…

【网络协议】聊聊TCP的三挥四握

上一篇我们说了网络其实是不稳定的&#xff0c;TCP和UDP其实是两个不同的对立者&#xff0c;所以TCP为了保证数据在网络中传输的可靠性&#xff0c;从丢包、乱序、重传、拥塞等场景有自己的一套打法。 TCP格式 源端口和目标端口是不可缺少的&#xff0c;用以区分到达发送给拿…

windows安装数据库MySQL

windows安装数据库MySQL 文章目录 windows安装数据库MySQL一、MySQL官网下载压缩包二、在D盘新建文件夹D:\MySQL&#xff0c;将下载的压缩包解压到该文件夹下三、配置环境变量四、通过命令行模式安装、启用、配置SQL服务 一、MySQL官网下载压缩包 下载地址&#xff1a;https:/…

APP逆向基础(APK流程)

APK的基本结构 Android体系结构和APK基本结构-CSDN博客 APK 打包流程 【Android 安装包优化】APK 打包流程 ( 文件结构 | 打包流程 | 安装流程 | 安卓虚拟机 )_adnroid 安装包优化,打指定资源_韩曙亮的博客-CSDN博客 APK安装流程

Go 实现插入排序算法及优化

插入排序 插入排序是一种简单的排序算法&#xff0c;以数组为例&#xff0c;我们可以把数组看成是多个数组组成。插入排序的基本思想是往前面已排好序的数组中插入一个元素&#xff0c;组成一个新的数组&#xff0c;此数组依然有序。光看文字可能不理解&#xff0c;让我们看看…

Power BI 傻瓜入门 9. 设计和部署数据模型

本章内容包含&#xff1a; 详细说明设计数据模型的技术要求Power BI Desktop中基本数据模型的设计将数据模型从Power BI Desktop发布到Power BI Services 在数据进入Power BI后对其进行操作既是一门艺术&#xff0c;也是一门科学。导入到任何应用程序中的数据不仅需要注意数据…

【论文阅读】(2023TPAMI)PCRLv2

目录 AbstractMethodMethodnsU-Net中的特征金字塔多尺度像素恢复多尺度特征比较从多剪切到下剪切训练目标 总结 Abstract 现有方法及其缺点&#xff1a;最近的SSL方法大多是对比学习方法&#xff0c;它的目标是通过比较不同图像视图来保留潜在表示中的不变合判别语义&#xff…

[AutoSar NVM] 存储架构

依AutoSAR及公开知识辛苦整理&#xff0c;禁止转载。 专栏 《深入浅出AutoSAR》&#xff0c; 全文 2900 字. 图片来源&#xff1a; 知乎 汽车的ECU内存中有很多不同类型的变量&#xff0c;这些变量包括了车辆各个系统和功能所需的数据。大部分变量在ECU掉电后就会丢失&#x…

深入探索Sharding JDBC:分库分表的利器

随着互联网应用的不断发展和用户量的不断增加&#xff0c;传统的数据库在应对高并发和大数据量的场景下面临着巨大的挑战。为了解决这一问题&#xff0c;分库分表成为了一个非常流行的方案。分库分表主流的技术包括MyCat和Sharding JDBC。我们来通过一张图来了解这两者有什么区…

性能测试jmeter命令行运行+html测试报告解读

windows下打开jmeter的运行窗口&#xff0c;可以看到提示不要用GUI模式进行负载测试&#xff0c;如果要用负载测试&#xff0c;用cli模式&#xff0c;因为GUI模式运行jmeter比较消耗性能。 命令行模式 windows下找到jemeter所在文件夹&#xff0c;打开cmd输入命令。 jmeter -n…

Centos安装gitlabce

服务器配置要求&#xff08;2c4g&#xff09; 1、 安装其他组件 yum install -y curl policycoreutils-python openssh perl2、 安装Postfix服务以发送电子邮件通知&#xff0c;启动服务并自启 yum -y install postfix systemctl enable postfix --now3、 安装gitlab&#xf…