使用websocket前后台通信实时刷新

websocket的使用步骤(该流程亲测有效,耐心看完。)

1.创建socket后台代码
WebSocketServer :

@ServerEndpoint("/jswebsocket")
@Component
public class WebSocketServer {
	MyNewThread thread1 = new MyNewThread();//自定义的线程,用于实时监听数据变化
	// 开启线程
	Thread thread = new Thread(thread1);
	// 用来存放每个客户端对应的MyWebSocket对象。
	private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
	private javax.websocket.Session session = null;

	/**
	 * @ClassName: onOpen
	 * @Description: 开启连接的操作
	 */
	@OnOpen
	public void onOpen(Session session, EndpointConfig config) throws IOException {
		// 获取WebsocketConfig.java中配置的“sessionId”信息值
		
		String httpSessionId = (String) config.getUserProperties().get("sessionId");
		this.session = session;
		String tablekey = session.getRequestParameterMap().get("tablekey").get(0);// 获取表名称,前台传递的参数
		thread1.setInitname(initname);
		thread1.setTablekey(tablekey);
		webSocketSet.add(this);
		// 开启一个线程对数据库中的数据进行轮询
		thread.start();
		System.out.println("1.进入后台方法onOpen");

	}

	/**
	 * 给服务器发送消息告知数据库发生变化
	 * 
	 * @param count
	 */
	@OnMessage
	public void onMessage(String message) {
		System.out.println("2.进入后台方法onMessage");
		try {
			sendMessage(message);//进入内部类,这个方法用户自定义
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 出错操作
	 * 
	 * @param error
	 */
	@OnError
	public void onError(Throwable error) {
		System.out.println("5.进入后台方法onError");
		error.printStackTrace();
	}
	/**
	 * @ClassName: onClose
	 * @Description: 连接关闭的操作
	 */
	@OnClose
	public void onClose() {
		System.out.println("4.进入方法后台onClose");
		thread1.stopMe();
		webSocketSet.remove(this);
	}
	/**
	 * 此方法是被调用的方法,所以没注解,这里才是真正处理逻辑的地方,可以给前台传输你想要传输的内容。
	 * @param message 
	 * 
	 * @throws IOException
	 *             发送自定义信号,表示告诉前台,数据库发生改变了,需要刷新
	 */
	public void sendMessage(String message) throws IOException {
		// 群发消息
		for (WebSocketServer item : webSocketSet) {
			item.session.getBasicRemote().sendText(message);
		}
	}

2.创建websocket相关的js
socket.js:

		var websocket = null;
        if ('WebSocket' in window) {//判断当前浏览器是否支持WebSocket
        	var tablekey="yjsskb";
        	var LocalhostIpAndPort = "127.0.0.1:8080";
        	 var url = "ws://"+LocalhostIpAndPort+"/demo/jswebsocket?tablekey=" + tablekey;
        	 websocket = new WebSocket(url);
            //websocket = new WebSocket("ws://"+LocalhostIpAndPort+"/dtjg/jswebsocket");
            console.log("websocket 建立连接22");
        }
        else {
          //  alert('当前浏览器不支持websocket');
        }
        //连接成功建立的回调方法
        websocket.onopen = function () {
        	console.log("websocket onopen连接成功");
        }
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
        	var method=event.data;      	
        	console.log("websocket onmessage接收到消息");  
        }
        //连接发生错误的回调方法
        websocket.onerror = function () {
        	console.log("websocket onerror连接发生错误");
        };
        //连接关闭的回调方法
        websocket.onclose = function () {
        	console.log("websocket onclose连接关闭");
        }
        //监听窗口关闭事件,当窗口关闭时,主动去关闭WebSocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            closeWebSocket();
        }
        //关闭WebSocket连接
        function closeWebSocket() {
            websocket.close();
        }

3.jsp页面引入socket.js

<script type="text/javascript" src="<l:asset path='socket.js'/>"></script>

4.调用socket方法(3种)

方法1: js页面主动调用发起请求(比如点击某个按钮,触发)

websocket.send(message);

方法2:后台主动调用socket发送方法 (比如后台新增时,触发)

WebSocketServer socket=new WebSocketServer ();
socket.onMessage(0);

方法3:实时动态监听(例如监听数据库某个数据是否发生变化)
创建线程,线程先对数据库中的数据查询一次,存在oldcount变量中,然后再一直对数据库中的数据进行轮询,newcount与oldcount不同的话就发送消息给WebSocket实现类。
MyNewThread:

@Component
public class MyNewThread implements Runnable {
	// 普通类获取service对象,否则会报空指针
	@Autowired
	private WebsocketService websocketService;
	public static MyNewThread testUtils;
	 // dataSource:注册数据源
    private static DataSource dataSource = null;
    private String tablekey;
    private String initname;
    
	// 下面的注解一定要有哈
	@PostConstruct
	public void init() {
		testUtils = this;
	}
	
	// 设置循环状态
	private boolean stopMe = true;

	public void stopMe() {
		stopMe = false;
	}
	 // 获取连接信息
    private static DataSource getDataSource() {
        if (dataSource == null) {
            dataSource = (DataSource) SpringWebContextUtils.getBean("dataSource");
        }
        return dataSource;
    }
    public static List<Map<String, Object>> excusql(String sql) {
    	Queryer queryer1 = new Queryer();
        queryer1.setDataSource(getDataSource());
		queryer1.setSql(sql);
         queryer1.compile();
         return queryer1.execute();
    }
	@Override
	public void run() {
		String tablename=tablekey;
		String initnames=initname;
		String initsnm="";
		String zxsql="";
		  String sql="SELECT INDEXSQL_SQLSTR, INDEXSQL_BMLIST, INDEXSQL_GLGX FROM DTJG_INTE.DQC_INDEX_SQL WHERE INDEXSQL_ID='"+tablename+"'";
		  List<Map<String, Object>> excusqllist = excusql(sql); 
		  String oldcount=null;
		  if(excusqllist.size()>0) { 
			  zxsql=(String) excusqllist.get(0).get("INDEXSQL_SQLSTR"); 
			   initsnm=(String) excusqllist.get(0).get("INDEXSQL_BMLIST"); 
			  List<Map<String, Object>> zxsqllist = excusql(zxsql);
			  oldcount=(String) zxsqllist.get(0).get("SL"); 
			  }
		  WebSocketServer wbs = new WebSocketServer(); 
		  while (stopMe) {
		  List<Map<String, Object>> excusql = excusql(zxsql); 
		  if(excusql.size()>0) {
			  String newcount=(String) excusql.get(0).get("SL");
		  if(!newcount.equals(oldcount)) {
			  oldcount=newcount; wbs.onMessage(initsnm); 
			  } 
		  } 
		  }
	}
	public String getTablekey() {
		return tablekey;
	}
	public void setTablekey(String tablekey) {
		this.tablekey = tablekey;
	}
	public String getInitname() {
		return initname;
	}
	public void setInitname(String initname) {
		this.initname = initname;
	}
}

在这里插入图片描述

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值