【Java后端向前端推送消息】

【Java后端向前端推送消息】

1、WebSocketConfig配置类

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration @EnableWebSocket publicclassWebSocketConfig{ @Bean public ServerEndpointExporter serverEndpointExporter(){returnnewServerEndpointExporter();}}

2、WebSocket消息发送接收

import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import org.springframework.util.ObjectUtils;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.util.Map;import java.util.Set;import java.util.concurrent.ConcurrentHashMap; @Slf4j @Component @ServerEndpoint(value ="/web/{id}")publicclassWebSocketProcess{/* * 持有每个webSocket对象,以key-value存储到线程安全ConcurrentHashMap, */privatestatic ConcurrentHashMap<Long, WebSocketProcess> concurrentHashMap =newConcurrentHashMap<>(12);/** * 会话对象 **/private Session session;/* * 客户端创建连接时触发 * */ @OnOpen publicvoidonOpen(Session session, @PathParam("id") long id){//每新建立一个连接,就把当前客户id为key,this为value存储到map中this.session = session; concurrentHashMap.put(id,this); log.info("Open a websocket. id={}", id);}/** * 客户端连接关闭时触发 **/ @OnClose publicvoidonClose(Session session, @PathParam("id") long id){//客户端连接关闭时,移除map中存储的键值对 concurrentHashMap.remove(id); log.info("close a websocket, concurrentHashMap remove sessionId= {}", id);}/** * 接收到客户端消息时触发 */ @OnMessage publicvoidonMessage(String message, @PathParam("id") String id){ log.info("receive a message from client id={},msg={}", id, message);}/** * 连接发生异常时候触发 */ @OnError publicvoidonError(Session session, Throwable error){ log.error("Error while websocket. ", error);}/** * 发送消息到指定客户端 * * @param id * @param message */publicvoidsendMessage(long id, String message) throws Exception {//根据id,从map中获取存储的webSocket对象 WebSocketProcess webSocketProcess = concurrentHashMap.get(id);if(!ObjectUtils.isEmpty(webSocketProcess)){//当客户端是Open状态时,才能发送消息if(webSocketProcess.session.isOpen()){ webSocketProcess.session.getBasicRemote().sendText(message);}else{ log.error("websocket session={} is closed ", id);}}else{ log.error("websocket session={} is not exit ", id);}}/** * 发送消息到所有客户端 */publicvoidsendAllMessage(String msg) throws Exception { log.info("online client count={}", concurrentHashMap.size()); Set<Map.Entry<Long, WebSocketProcess>> entries = concurrentHashMap.entrySet();for(Map.Entry<Long, WebSocketProcess> entry : entries){ Long cid = entry.getKey(); WebSocketProcess webSocketProcess = entry.getValue(); boolean sessionOpen = webSocketProcess.session.isOpen();if(sessionOpen){ webSocketProcess.session.getBasicRemote().sendText(msg);}else{ log.info("cid={} is closed,ignore send text", cid);}}}}

3、消息推送Controller

import com.xyl.web.controller.common.WebSocketProcess;import com.xyl.web.controller.common.WebSocketServer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/testws")publicclassWebSocketController{/** * 注入WebSocketProcess **/ @Autowired private WebSocketProcess webSocketProcess;/** * 向指定客户端发消息 * * @param id */ @PostMapping(value ="sendMsgToClientById")publicvoidsendMsgToClientById(@RequestParam long id, @RequestParam String text){try{ webSocketProcess.sendMessage(id, text);}catch(Exception e){ e.printStackTrace();}}/** * 发消息到所有客户端 * * @param text */ @PostMapping(value ="sendMsgToAllClient")publicvoidsendMsgToAllClient(@RequestParam String text){try{ webSocketProcess.sendAllMessage(text);}catch(Exception e){ e.printStackTrace();}}/** * 定时向客户端推送消息 * @throws Exception */ @Scheduled(cron ="0/5 * * * * ?")privatevoidconfigureTasks() throws Exception { webSocketProcess.sendAllMessage("向前端推送消息内容");}}

4、测试HTML

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>websocket测试</title><script src="http://code.jquery.com/jquery-2.1.1.min.js"></script></head><body><div id="content"></div></body><script type="text/javascript">$(function(){var ws;//检测浏览器是否支持webSocketif("WebSocket"in window){$("#content").html("您的浏览器支持webSocket!");//模拟产生clientIDlet clientID = Math.ceil(Math.random()*100);//创建 WebSocket 对象,注意请求路径!!!! ws =newWebSocket("ws://127.0.0.1:9095/web/"+clientID);//与服务端建立连接时触发 ws.onopen=function(){$("#content").append("<p>与服务端建立连接建立成功!您的客户端ID="+clientID+"</p>");//模拟发送数据到服务器 ws.send("你好服务端!我是客户端 "+clientID);}//接收到服务端消息时触发 ws.onmessage=function(evt){let received_msg = evt.data;$("#content").append("<p>接收到服务端消息:"+received_msg+"</p>");};//服务端关闭连接时触发 ws.onclose=function(){ console.error("连接已经关闭.....")};}else{$("#content").html("您的浏览器不支持webSocket!");}})</script></html>

Read more

2026年AI编程工具全景图:GitHub Copilot vs Cursor vs Codeium,我如何选择?

2026年AI编程工具全景图:GitHub Copilot vs Cursor vs Codeium,我如何选择?

文章目录 * 前言 * 一、我的使用场景与测试环境 * 二、GitHub Copilot:全球生态标杆 * 核心优势实测 * 性能数据记录 * 鸿蒙开发适配度 * 三、Cursor:专家级重构利器 * 重构能力深度测试 * 多文件分析能力 * 四、Codeium:极致免费的性价比之选 * 免费策略的深度体验 * 响应速度实测 * 中文支持的优势 * 五、鸿蒙开发场景专项测试 * 测试1:ArkTS组件生成 * 测试2:分布式能力集成 * 测试3:性能优化建议 * 六、2026年价格策略对比 * 七、我的实际使用组合 * 工作日使用方案 * 具体工作流 * 效率提升数据 * 八、选择建议:根据你的场景决策 * 场景1:学生/初学者/零预算 * 场景2:前端/鸿蒙开发者 * 场景3:全栈/团队协作

2026最火的6款免费AI写作软件测评:ai写网文哪个好用?这款ai消痕工具

2026最火的6款免费AI写作软件测评:ai写网文哪个好用?这款ai消痕工具

很多朋友想在业余时间写写番茄、起点网文或者搞搞短剧赚点外快,但总是卡在“憋不出字”或者“大纲写崩”上。现在都2026年了,用ai写作软件来辅助写小说早就不是秘密了。 但是,网文平台的审核越来越严,很多新手直接用AI生成的文章发出去,立马就被平台判定为“AI生成”导致限流,不仅没流量,连全勤奖都拿不到。 今天,我们就抛开那些晦涩难懂的技术术语,用大白话给大家实测目前市面上热度最高的6款免费ai写作平台。到底ai写网文哪家强?怎么解决让人头疼的“机器味”?这篇超详细的避坑指南,建议想靠文字搞钱的朋友直接收藏! 一、 6大热门免费AI小说工具优缺点大盘点 我们选了大家最常搜的几款工具,直接看它们在实际写小说、写剧本时的真实表现。 1. 豆包:起名和找灵感的“点子王” * 优点:速度飞快,完全免费。你如果卡文了,或者不知道主角叫什么、书名怎么起才能吸引人,直接问豆包,它能一秒钟给你吐出几十个极其符合抖音、小红书调性的网感标题和名字。 * 缺点:千万别让它直接给你写正文!它的AI味太重了,动不动就是“嘴角勾起一抹弧度”、“倒吸一口凉气”。把这种文发到小说平台,

2026 免费 AI 编程助手排行榜:文心快码、Copilot 与 Cursor 深度评测

2026年度核心结论速览 基于 IDC《中国生成式 AI 代码工具评估 2025》 及 Stack Overflow 2026 开发者调查 数据,我们将主流工具分为三个梯队。 * 行业现状:据 McKinsey 报告显示,AI 辅助开发使新手工程师效率提升 2倍,熟练开发者编码速度提升 55%。 * Tier 0 (工程化首选):文心快码 (Comate)。唯一在 IDC 评估中斩获 8项满分 的产品,支持企业级免费开通与个人免费使用,是目前唯一具备完整“代码智能体(Coding Agent)”形态的工具。 * Tier 1 (生态首选):GitHub Copilot。全球生态最强,拥有 85% 的开发者信心提升率,适合开源社区重度用户。 * Tier

【保姆级教程】llama.cpp大模型部署全攻略:CPU/GPU全兼容,小白也能轻松上手!

【保姆级教程】llama.cpp大模型部署全攻略:CPU/GPU全兼容,小白也能轻松上手!

一、简介 * • llama.cpp 是一个在 C/C++ 中实现大型语言模型(LLM)推理的工具 * • 支持跨平台部署,也支持使用 Docker 快速启动 * • 可以运行多种量化模型,对电脑要求不高,CPU/GPU设备均可流畅运行 * • 开源地址参考:https://github.com/ggml-org/llama.cpp • 核心工作流程参考: 二、安装与下载模型(Docker方式) 1. 搜索可用模型 • 这里以 qwen3-vl 模型为例,提供了多种量化版本,每种版本的大小不一样,根据自己的电脑性能做选择,如选择(模型+量化标签):Qwen/Qwen3-VL-8B-Instruct-GGUF:Q8_0 • 可以在huggingface官网中搜索可用的量化模型:https://huggingface.co/models?search=