JFinal整合Websocket

devtools/2024/11/14 14:52:15/
学习笔记,供大家参考
总结的不错的话,记得点赞收藏关注哦!
  1. javaxwebsocketapi_4">导入JAR包 javax.websocket-api

    <dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version><scope>provided</scope>
    </dependency>
    
  2. 编写WebSocket.class

    package cn.bigchin.spark.app.ws;import cn.bigchin.spark.Spark;
    import cn.bigchin.spark.SparkConst;
    import cn.bigchin.spark.expand.event.SparkEvent;
    import com.jfinal.kit.Kv;
    import com.jfinal.kit.StrKit;
    import com.jfinal.log.Log;
    import javax.websocket.*;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;import java.io.IOException;
    import java.util.concurrent.ConcurrentSkipListMap;/*** TODO:** @author 一川死水 (yichuan95@126.com)* @Date 2024/9/19*/
    @ServerEndpoint("/websocket/{id}")
    public class WebSocket {Log log = Log.getLog(WebSocket.class);private String id;//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;//concurrent包的线程安全Set,用来存储每个客户端对应的MySocket对象private static ConcurrentSkipListMap<String, WebSocket> webSocketMap = new ConcurrentSkipListMap<>();@OnOpenpublic void onOpen(@PathParam("id") String id, Session session) throws IOException {this.session = session;this.id = id;webSocketMap.put(id, this);log.debug(String.format("用户:%s已连接", id));}@OnClosepublic void onClose(Session session) {log.debug(String.format("用户:%s已断开链接"));webSocketMap.remove(id);}@OnErrorpublic void onError(Session session, Throwable error) {error.printStackTrace();log.debug("链接异常", error);));}@OnMessagepublic void onMessage(Session session, String message) throws IOException {// 收到消息,根据自己的业务作实际处理判断是否在线,如原样发送回客户端session.getBasicRemote().sendText(message);}/*** TODO:群发自定义消息(建议使用此方法)** @param id      用户id id为null时 ,为群发* @param message 消息内容*/public static void sendMessage(String id, String message) throws IOException {for (String idKey : webSocketMap.keySet()) {if (StrKit.isBlank(id)) {webSocketMap.get(idKey).session.getAsyncRemote().sendText(message);} else {if (idKey.equals(id)) {webSocketMap.get(idKey).session.getAsyncRemote().sendText(message);}}}}
    }
    
  3. 如果是在undertow 下启动,则要继续添加依赖,如果是tomcat环境下,可跳过这一步

     <!-- jfinal-undertow  --><dependency><groupId>com.jfinal</groupId><artifactId>jfinal-undertow</artifactId><version>2.0</version></dependency><!-- 开发 WebSockets 时开启下面的依赖 --><dependency><groupId>io.undertow</groupId><artifactId>undertow-websockets-jsr</artifactId><version>2.0.28.Final</version></dependency>
    

    然后在undertow启动添加websocket集成

     //configClass自行替换成自己的配置类UndertowServer server = UndertowServer.create(configClass);server.configWeb(webBuilder -> {webBuilder.addWebSocketEndpoint(WebSocket.class);});server.start();
    
  4. websocket_119">不拦截websocket的访问

    //在自己的配置类中添加拦截,
    //如果WebSocket 中的@ServerEndpoint配置地址有带.的,如@ServerEndpoint("/websocket.ws/{id}"),则无需添加拦截,因为带 "." 字符的 url 不会被 jfinal 框架当成 action,所以直接跳过了
    public void configHandler(Handlers me) {me.add(new UrlSkipHandler("^/websocket", false));
    }
    
  5. 前端js代码

    java">let id='1'
    let webSocket = null;
    if (window.WebSocket) {if(Protocol == 'https'){websocket = new WebSocket('wss://' + host + '/websocket/' + id);}else{websocket = new WebSocket('ws://' + host + '/websocket/' + id);}      
    } else {   console.log("您的浏览器不支持WebSocket");return;
    }
    //打开事件
    webSocket.onopen = function (){console.log("WebSocket已打开");//webSocket.send("这是来自客户端的消息"+id+new Date());
    }
    //获得消息事件
    webSocket.onmessage = function (message){//收到消息,自行处理业务逻辑console.log(message)
    }
    //关闭事件
    webSocket.onclose = function (){console.log("Socket已关闭");
    }
    //发生了错误
    webSocket.onerror = function (){console.log("Socket发生了错误");
    }
    //发送消息
    function send(message) {websocket.send(message);
    }
    //当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口
    window.onbeforeunload = function () {websocket.close();
    }
    

http://www.ppmy.cn/devtools/114900.html

相关文章

Git使用手册

1、初识Git 概述&#xff1a;Git 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理项目版本管理。 知识点补充&#xff1a; 版本控制&#xff1a;一种记录一个或若干文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。 分布式&#xff1a;每个人…

JAVA自助高效安全无人台球茶室棋牌室系统小程序源码

​探索“自助高效安全无人台球茶室棋牌室系统”的奇妙之旅 &#x1f3b1;&#x1f375;&#x1f3b2; &#x1f50d; 初见惊艳&#xff1a;未来娱乐新体验 &#x1f50d; 走进这家无人值守的台球茶室棋牌室&#xff0c;第一感觉就像是穿越到了未来&#xff01;没有繁琐的前台登…

中间件知识点-消息中间件(Rabbitmq)一

消息中间件介绍 MQ的作用(优点)主要有以下三个方面&#xff1a; a.异步 b.解耦 c.削峰 MQ的作用(缺点)主要有以下三个方面&#xff1a; a.系统可用性降低 b.系统复杂度提高 c.存在消息一致性问题需要解决 备注&#xff1a; 引入MQ后系统的复杂度会大大提高。 以前服务之间可以…

前后端分离集成CAS单点登录

修改nginx worker_processes 1; events {worker_connections 1024; } http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 80;server_name localhost;location /api/ {proxy_pass htt…

reg和wire的区别 HDL语言

文章目录 数据类型根本区别什么时候要定义wire小结 数据类型 HDL语言有三种数据类型&#xff1a;寄存器数据类型&#xff08;reg&#xff09;、线网数据类型&#xff08;wire&#xff09;、参数数据类型&#xff08;parameter&#xff09;。 根本区别 reg&#xff1a; 寄存器…

Java | Leetcode Java题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; class Solution {public int strongPasswordChecker(String password) {int n password.length();int hasLower 0, hasUpper 0, hasDigit 0;for (int i 0; i < n; i) {char ch password.charAt(i);if (Character.isLowerCase(ch))…

微信小程序06-综合项目点餐系统

零、文章目录 微信小程序06-综合项目点餐系统 1、项目开发准备 &#xff08;1&#xff09;开发背景 现如今&#xff0c;相比以服务员为中介完成点餐、送餐、买单的传统点餐方式&#xff0c;越来越多的餐厅开始使用微信小程序进行点餐。商家可以在微信小程序中添加点餐和收款…

将阮一峰老师的《ES6入门教程》的源码拷贝本地运行和发布

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 阮一峰老师的《ES6入门教程》应该是很多同学学习 ES6 知识的重要参考吧&#xff0c;应该也有很多同学在看该文档的时候&#xff0c;想知道这个教程的前端源码是怎么实现的&#xff0c;也可能有同学下载…