jFinal整合webocket

  • 【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
  • 【创作不易,点个赞就是对我最大的支持】

前言

仅作为学习笔记,供大家参考
总结的不错的话,记得点赞收藏关注哦!

踩过的坑:

  • Jfinal自带的服务器是jetty版本低是不支持websocket的
  • Tomcat8.5以上才支持websocket的

导入jar包tomcat-websocket-api-7.0.47.jar

1.pom形式

        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-websocket-api</artifactId>
            <version>7.0.47</version>
            <scope>provided</scope>
        </dependency>

2.jar包形式
在这里插入图片描述
下拉选择7.0.47
在这里插入图片描述
下载好去自己的maven库找jar包就行

编写拦截器Headler

 package com.tides.app.handler;
import com.jfinal.handler.Handler;
import com.jfinal.kit.StrKit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.regex.Pattern;
/**
 * @ClassName WebSocketHandler
 * @Create 2021年5月19日10:21:17
 */
public class WebSocketHandler extends Handler {

    private Pattern filterUrlRegxPattern;

    public WebSocketHandler(String filterUrlRegx) {
    	System.out.println("进入WebSocket配置");
        if (StrKit.isBlank(filterUrlRegx))
            throw new IllegalArgumentException("The para filterUrlRegx can not be blank.");
        filterUrlRegxPattern = Pattern.compile(filterUrlRegx);
    }
    @Override
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
    	if (filterUrlRegxPattern.matcher(target).find()) {
    		System.out.println("j进入了ws的handle"+target);
            return ;
    	}else {
            next.handle(target, request, response, isHandled);
    	}
    }
}

websocketController消息处理类

package com.tides.sys.websocket.controller;
import com.jfinal.aop.Clear;
import com.tides.common.controller.BaseController;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

/**
 * @ClassName WebSocketController
 * @Create 2021年5月19日10:21:17
 * 记得配置路由  add("/websocket", WebSocketController.class);(也可不配置,我为了保险起见)
 */
@ServerEndpoint("/websocket")
@Clear
public class WebSocketController extends BaseController  {
	 //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private  Session session;
    //concurrent包的线程安全Set,用来存储每个客户端对应的MySocket对象
    private static CopyOnWriteArraySet<WebSocketController> webSocketSet = new CopyOnWriteArraySet<>();
    @OnOpen
    public void onOpen(Session session) {
    	this.session=session;
    	webSocketSet.add(this);
        System.out.println("连接打开了OPEN");
    }
    /**
     * 收到客户端消息时触发
     */
    @OnMessage
    public void onMessage(Session session, String key) throws IOException {
        //向客户端返回发送过来的消息
        System.out.println("发送一条消息:--"+key);
        session.getBasicRemote().sendText(key);//推送发送的消息
        sendMessage("********************调用send");
    }
    /**
     * 服务端主动发送消息(不建议使用此方法)
     */
    public  void  sendMessage(String message) throws IOException{
    	System.out.println("***************消息为:"+message);
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 群发自定义消息(建议使用此方法)
     * @param sid 用户id sid为null时 ,为群发
     * @param message 消息内容
     * 2021年5月19日10:21:17
     */
    public static void sendInfo(WsMessage wsMessage) throws IOException{
    	System.out.println("准备发送消息:"+wsMessage.getMessageContent().toString());
    	System.out.println("webSocketSet的size:"+webSocketSet.size());
        for (WebSocketController item :webSocketSet){
        	System.out.println("item:"+item.toString());
            try {
                //这里可以设定只推送给这个sid的,为null则全部发送
                   // item.sendMessage(message); item.session.getBasicRemote().sendText(wsMessage.MessageJSONtoString());
            }catch (IOException e){
                continue;
            }
        }
    }
    /**
     * 异常时触发
     */
    @OnError
    public void onError(Throwable throwable,Session session) {}
    /**
     * 关闭连接时触发
     */
    @OnClose
    public void onClose(Session session) {
    	webSocketSet.remove(this);
        System.out.println("连接关闭了~~~~(>_<)~~~~");
    }
}

jfinal的Config配置类

 	@Override
	public void configHandler(Handlers me) {
		me.add(new ContextPathHandler("ctx"));
		//me.add(new APINotFoundHandler());
		me.add(new WebSocketHandler("^/websocket"));
		me.add(new UrlSkipHandler("^/websocket", false));
	}

前台js

 var webSocket = null;
	var accountNum=$("#accountNum").val();
	if (typeof (WebSocket) == "undefined"){
		console.log("您的浏览器不支持WebSocket");
	}else{
		console.log("您的浏览器支持WebSocket");
		//实现WebSocket对象,指定要连接的服务器地址与端口 建立连接
		webSocket = new WebSocket("ws://127.0.0.1:8080/websocket");
		//打开事件
		webSocket.onopen = function (){
			console.log("Socket 已打开");
			//webSocket.send("这是来自客户端的消息"+location.href+new Date());
		}
		//获得消息事件
		webSocket.onmessage = function (msg){
			console.log(msg.data)
			var json = eval('(' + msg.data + ')');
			console.log(json.messageType);
			console.log(json.messageContent.loginId);
			console.log("页面oa:"+accountNum);
			//发现消息进入 开始处理前端触发逻辑
			if (json.messageContent.loginId==accountNum && json.messageContent.rzStatus==1){
				//$('#msgData').html(msg.data);
				document.location="http://127.0.0.1:8080/personal/myAuthentication";
			}else{
				layer.msg("用户信息错误,请使用本人实名支付宝进行扫码!",{icon:5,time:5000});
			}
		}
		//发送消息
		function send() {
		  var message = document.getElementById('text').value;
		  websocket.send(message);
		  }
		//关闭事件
		webSocket.onclose = function (){
			console.log("Socket已关闭");
		}
		//发生了错误
		webSocket.onerror = function (){
			alert("Socket发生了错误");
		}
	}

消息类型(可有可无)

package com.tides.sys.websocket.controller;
/**
 * 定义消息类型
 * @author Kang
 * 2021年5月19日10:21:17
 */
public  class WsMessageType {
		
		public static int MessageRz=1;
		public static int MessageOnlineCount=2;
}

消息类(可有可无)

package com.tides.sys.websocket.controller;

import java.util.Map;

import org.apache.commons.collections.map.HashedMap;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.json.Json;

import cn.hutool.json.JSON;
/**
 * 消息类
 * @author Kang
 * 2021年5月19日16:16:21
 *
 */
public class WsMessage {
	private Map<String,Object>  messageContent;
	private int messageType;
	public String MessagetoString() {
		Map<String, Object> map=new HashedMap();
		map.put("messageType", this.messageType);
		map.put("messageContent", this.messageContent);
		return map.toString();
	}
	public String MessageJSONtoString() {
		JSONObject json=new JSONObject();
		json.put ("messageType", this.messageType);
		json.put("messageContent", this.messageContent);
		return json.toString();
	}
	public  WsMessage(int messageType,Map<String,Object> messageContent) {
		this.messageContent=messageContent;
		this.messageType=messageType;
	}
	public Map<String, Object> getMessageContent() {
		return messageContent;
	}
	public void setMessageContent(Map<String, Object> messageContent) {
		this.messageContent = messageContent;
	}
	public int getMessageType() {
		return messageType;
	}
	public void setMessageType(int messageType) {
		this.messageType = messageType;
	}
}

创作不易,点个赞就是对我最大的支持~


公众号:程序员温眉

在这里插入图片描述
CSDN:程序员温眉

每天进步一点点的程序员

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值