jfinal websocket的配置以及实现。

大神可以去看看(反正我也基本看不懂)https://my.oschina.net/u/136848/blog/781896

1.不用配置WebRoot/WEB-INF下的web.xml文件

2.config只配置一句(其实还有后面有补充)

AlarmThreadController.getInstance().start();//这里就是关键

package com.bytech.common;

import com.bytech.controller.AlarmCodeController;
import com.bytech.controller.AlarmController;
import com.bytech.controller.AlarmThreadController;
import com.bytech.controller.AppSystemController;
import com.bytech.controller.CustomerController;
import com.bytech.controller.IndexController;
import com.bytech.controller.ShellController;
import com.bytech.controller.StatusController;
import com.bytech.controller.SystemBrandController;
import com.bytech.controller.SystemCustomerController;
import com.bytech.controller.UserController;
import com.bytech.controller.UserOperationController;
import com.bytech.handler.WebSocketHandler;
import com.bytech.model.Alarm;
import com.bytech.model.AlarmCode;
import com.bytech.model.AppSystem;
import com.bytech.model.Customer;
import com.bytech.model.Status;
import com.bytech.model.SystemBrand;
import com.bytech.model.SystemCustomer;
import com.bytech.model.User;
import com.bytech.utiltool.ServerPush;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.handler.Handler;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.render.ViewType;

public class CommonConfig extends JFinalConfig {

	@Override
	public void configConstant(Constants me) {
		// TODO Auto-generated method stub
		loadPropertyFile("config.properties");
		me.setDevMode(getPropertyToBoolean("devMode", false));
		me.setEncoding("UTF-8");
		me.setViewType(ViewType.JSP);
		me.setUploadedFileSaveDirectory(PathKit.getWebRootPath()+"\\uploads");
	}


	@Override
	public void configPlugin(Plugins me) {
		// TODO Auto-generated method stub
		C3p0Plugin c3p0Plugin =new C3p0Plugin(getProperty("jdbcUrl"),
				getProperty("user"),getProperty("password").trim());
		me.add(c3p0Plugin);
		ActiveRecordPlugin arp=new ActiveRecordPlugin(c3p0Plugin);
		me.add(arp);
		/*************************
		 *    添加表映射
		 ************************/
		arp.addMapping("customer", "CustomerId",Customer.class);
		arp.addMapping("customer_system", "SystemId",SystemCustomer.class);
		arp.addMapping("status", "id",Status.class);
		arp.addMapping("system_brand", "id",SystemBrand.class);
		arp.addMapping("alarm", "AlarmId",Alarm.class);
		arp.addMapping("system_log", "LogId",AppSystem.class);
		arp.addMapping("alarm_code", "AlarmCode",AlarmCode.class);
		arp.addMapping("user", "id",User.class);
		
		AlarmThreadController.getInstance().start();//这里就是关键

		
		
	}

	@Override
	public void configInterceptor(Interceptors me) {
		// TODO Auto-generated method stub
		me.add(new SessionInViewInterceptor(true));
	}

	@Override
	public void configHandler(Handlers me) {
		// TODO Auto-generated method stub
		me.add(new WebSocketHandler());
	}

	@Override
	public void configRoute(Routes me) {
		// TODO Auto-generated method stub
		me.add("/customer", CustomerController.class, "");
		me.add("/systemcustomer", SystemCustomerController.class, "");
		me.add("/status", StatusController.class, "");
		me.add("/systemBrand", SystemBrandController.class, "");
		me.add("/alarm", AlarmController.class, "");
		me.add("/appSystem", AppSystemController.class, "");
		me.add("/userOperation", UserOperationController.class, "");
		me.add("/alarmCode", AlarmCodeController.class, "");
		me.add("/user", UserController.class, "");
		//shell脚本
		me.add("/shell", ShellController.class, "");
		me.add("/",IndexController.class);
		
	}
}

2.创建AlarmThreadController这个controller类。

package com.bytech.controller;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.bytech.model.Alarm;
import com.bytech.utiltool.ServerPush;

public class AlarmThreadController extends Thread {

	private static class SingletonHolder {
		private static AlarmThreadController instance = new AlarmThreadController();
	}

	public static AlarmThreadController getInstance() {
		return SingletonHolder.instance;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();//
		while (true) {
			try {
			//	this.sleep(30000); //这个是启动时间,必须确保config映射表内容走完。
						//其他内容运行完毕才走
						//AlarmThreadController.getInstance().start();//这里就是关键
// Date now = new Date(); // 当前时间// SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// String newTime = sf.format(now).toString();// List<Alarm> list = Alarm.dao.find("select AlarmId from alarm where AlarmTime >= ? ", newTime);// String idsJSON="";// if(list.size()!=0){// for (int i = 0; i < list.size(); i++) {// if(i==0){// idsJSON+=list.get(i).toJson();// }else if(i>0 && i<list.size()-1){// idsJSON+=","+list.get(i).toJson();// }else{// idsJSON+=","+list.get(i).toJson();// }// }// System.out.println(idsJSON);// String type="success";// String message="告警日志,新添加了"+list.size()+"条数据,请自行查看。";// ServerPush.broadcastAll(type,message,idsJSON);//这也是关键。// }} catch (Exception e) {e.printStackTrace();}}}// 把数据库里的数据,进行处理,转成long 和现在时间进行比较//public static long getDateLongVal(String str) {// int one = str.indexOf("AlarmTime:");// String str1 = str.substring(one + 10, one + 29);// String st1 = str1.replaceAll("-", "").replaceAll(":", "").replaceAll(" ", "");// return Long.parseLong(st1);//}}
 

 
上面AlarmThreadController继承了Thread(线程)重写了run方法 

在run方法里我调用了ServerPush类里的broadcastAll(type,message,idsJSON)方法

ServerPush.broadcastAll(type,message,idsJSON);//这也是关键。

3.创建ServerPush类

package com.bytech.utiltool;


import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
//注意此访问地址格式如:"ws://"+ window.location.host+"/${pageContext.request.contextPath}/game"是ws开头的,而不是以http:开头的.
@ServerEndpoint(value = "/socket")
public class ServerPush {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    static Map<String,Session> sessionMap = new Hashtable<String,Session>();
    
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("ServerPush="+session.getId());
    	sessionMap.put(session.getId(), session);
    }

    @OnMessage
    public void onMessage(String unscrambledWord, Session session) {
    	System.out.println("来自客户端的消息:" + unscrambledWord);
    	//取消报警
/*    	if(unscrambledWord.startsWith("cancel"))
    	{
    		String[] strarray = unscrambledWord.split(":");
    		AlarmMonitorThread.cancelAlarm(strarray[1], strarray[2]);
    	}*/
    	try {
            session.getBasicRemote().sendText("{type:'message',text:'"+unscrambledWord+"'}");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    @OnMessage
    public void receiveMessage(ByteBuffer b,Session session)
    {
        for(int i=0;i<b.capacity();i++)
        {
            System.out.println("msg="+b.getChar(i));
        }
        
    }
    /**
     * 广播给所有人
     * @param message
     */
    public static void broadcastAll(String type,String message,String data){
        Set<Map.Entry<String,Session>> set = sessionMap.entrySet();
        for(Map.Entry<String,Session> i: set){
            try {
            	i.getValue().getBasicRemote().sendText("{type:'"+type+"',text:'"+message+"',data:'"+data+"'}");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
    	sessionMap.remove(session.getId());
        logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }
    
    @OnError
    public void error(Session session, java.lang.Throwable throwable){
    	sessionMap.remove(session.getId());
        System.err.println("session "+session.getId()+" error:"+throwable);
    }
}
这个类你创建在那里就行。(我也基本看不懂)其主要目的就是调用broadcastAll方法广播给所有人。

i.getValue().getBasicRemote().sendText("{type:'"+type+"',text:'"+message+"',data:'"+data+"'}");这句话就是把对应的值传个前台。

4.config配置handler(不好意意思,之前忘了说了。不过我还是写了的)

@Override
public void configHandler(Handlers me) {
// TODO Auto-generated method stub
me.add(new WebSocketHandler());
}

5.创建WebSocketHandler类,直接附上源码

package com.bytech.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jfinal.handler.Handler;

public class WebSocketHandler extends Handler {

	public WebSocketHandler() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(String target, HttpServletRequest request,
			HttpServletResponse response, boolean[] isHandled) {
		// TODO Auto-generated method stub
		int index = target.indexOf("/socket");
        if (index == -1) {
            nextHandler.handle(target, request, response, isHandled);
        }

	}

}
至于为什么写和配置handler,作用应该是给"/socket"(这个路径进行放行。)

6.写webSocket的前端js代码

	var socket;
		if ('WebSocket' in window) {
			socket = new WebSocket("ws://"+ window.location.host
					+ "/DaHuaOperationCollect/socket");
		} else {
			console.log('不支持websocket');
		}
		//连接创建后调用
		socket.onopen = function() {
			console.log("连接成功...<br/>");
		};
		//接收到服务器消息后调用
		socket.onmessage = function(obj) {
		//	console.log(obj); //在页面观察它的数据
			var d = eval("(" + obj.data + ")"); //把数据转成json,不然不好用,后台传的是String
			var idsJSON = d.data;
		//	var type = d.type;
			var msg = d.text;
		//	console.log(idsJSON);
		//	console.log(msg);
			//async: false,
			jQuery.ajax({
				url : "./alarm/webSocketUpdataRowCon",
				type : "POST",
				data : {"ids" : idsJSON},
				success : function(obj) {
				//	console.log("state" + obj.state)
					if (obj.state == "0") {
						var r = obj.row;
						var len=r.length;
						//var str="";
						console.log("len="+len);
						queryAlarmPage1(len);
						
						
					//	console.log("zzzzzzzzzzzzzz");
					/* 	for (var i = 0; i<r.length; i++) {
 						 	str+="<tr class=\"danger\">"+
									"<td style=\"text-align: center; \">"+r[i].CustomerName+"</td>"+
									"<td style=\"text-align: center; \">"+r[i].SystemId+"</td>"+
									"<td style=\"text-align: center; \">"+r[i].AlarmContent+"</td>"+
									"<td style=\"text-align: center; \">"+r[i].AlarmTime+"</td>"+
									"<td style=\"text-align: center; \">"+r[i].DevIp+"</td>"+
									"<td style=\"text-align: center; \">"+r[i].Remark+"</td>"+
								"</tr>"; 
 						}
						$("#customerlist tbody tr:first").before(str); */
						
						layer.alert(msg, {
							skin : 'layui-layer-molv'//样式类名
							,closeBtn : 0
						}); 
						
					} else {
						layer.alert('实施更新数据失败。', {
							skin : 'layui-layer-molv'//样式类名
							,closeBtn : 0
						});
					}
				},
				error : function() {
					layer.alert('系统错误', {
						skin : 'layui-layer-molv'//样式类名
						,closeBtn : 0
					});
				},
				complete : function(obj) {
					if (obj.status == 200);
				}
			})

		};
		//关闭连接的时候调用
		socket.onclose = function() {
			console.log("close");
		};
		//出错时调用
		socket.onerror = function() {
			console.log("error");
		};
		
好了以上就是jfinal webSocket的配置 和实现的全部内容。
//接收到服务器消息后调用
socket.onmessage = function(obj) {把你要写的逻辑实现代码写在这里就行。}

若是不懂,仔细再看看,多打桩(就是用输出语句输出值看看)。(我也不怎会)


AlarmThreadController 文件重发一下
package com.bytech.controller;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.bytech.model.Alarm;
import com.bytech.utiltool.ServerPush;

public class AlarmThreadController extends Thread {
    private static String lastId = "0";
    private Logger logger = Logger.getLogger(this.getClass().getName());
	private static class SingletonHolder {
		private static AlarmThreadController instance = new AlarmThreadController();
	}

	public static AlarmThreadController getInstance() {
		return SingletonHolder.instance;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		Alarm alarm = Alarm.dao.findFirst("select max(AlarmId) as maxId from alarm");
		if(alarm != null && alarm.getInt("maxId") != null )
		{
		    lastId = String.valueOf(alarm.getInt("maxId"));
		}
        logger.info("begin ID:" + lastId);
		while (true) {
			try {
				sleep(30000);
				List<Alarm> list = Alarm.dao.find("select AlarmId  from alarm  where AlarmId>? group by AlarmId desc", lastId);
				String idsJSON="";
				if(list != null && list.size() > 0){
					for (int i = 0; i < list.size(); i++) {
						if(i==0){
						    lastId = String.valueOf(list.get(i).getInt("AlarmId"));
							idsJSON += list.get(i).getInt("AlarmId");
						}else if(i>0 && i<list.size()-1){
							idsJSON+=","+list.get(i).getInt("AlarmId");
						}else{
							idsJSON+=","+list.get(i).getInt("AlarmId");
						}
					}
					//System.out.println(idsJSON);
					String type="success";
					String message="告警日志,新添加了"+list.size()+"条数据,请自行查看。";
					ServerPush.broadcastAll(type,message,idsJSON);
				}
				logger.info("last Id:" + lastId);
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}



	// 把数据库里的数据,进行处理,转成long 和现在时间进行比较
	public static long getDateLongVal(String str) {
		int one = str.indexOf("AlarmTime:");
		String str1 = str.substring(one + 10, one + 29);
		String st1 = str1.replaceAll("-", "").replaceAll(":", "").replaceAll(" ", "");
		return Long.parseLong(st1);
	}

}













  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值