- 【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
- 【创作不易,点个赞就是对我最大的支持】
前言
仅作为学习笔记,供大家参考
总结的不错的话,记得点赞收藏关注哦!
目录
踩过的坑:
- 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:程序员温眉
每天进步一点点的程序员