学习笔记,供大家参考
总结的不错的话,记得点赞收藏关注哦!
-
javaxwebsocketapi_4">导入JAR包 javax.websocket-api
<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version><scope>provided</scope> </dependency>
-
编写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);}}}} }
-
如果是在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();
-
websocket_119">不拦截websocket的访问
//在自己的配置类中添加拦截, //如果WebSocket 中的@ServerEndpoint配置地址有带.的,如@ServerEndpoint("/websocket.ws/{id}"),则无需添加拦截,因为带 "." 字符的 url 不会被 jfinal 框架当成 action,所以直接跳过了 public void configHandler(Handlers me) {me.add(new UrlSkipHandler("^/websocket", false)); }
-
前端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(); }