websocket实现用户在线管理与心跳检测

var websocket;//websocket对象
var url = '';

$(function(){
	url = encodeURI('wss://'+'${oladress }');
	createWebSocket(url);
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
	websocket.close();
} 

var lockReconnect = false;  //避免websocket重复连接
function reconnect(url) {
    if(lockReconnect) return;
    lockReconnect = true;
    setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
        createWebSocket(url);
        lockReconnect = false;
    }, 2000);
}

function createWebSocket(url) {
    try{
        if('WebSocket' in window){
        	websocket = new WebSocket(url);//oladress在main.jsp页面定义
        }else if('MozWebSocket' in window){  
        	websocket = new MozWebSocket(url);
        }else{
            layui.use(['layer'],function(){
              var layer = layui.layer;
              layer.alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!"); 
            });
        }
        online();
    }catch(e){
        reconnect(url);
        console.log(e);
    }     
}

//心跳检测
var heartCheck = {
    timeout: 60000,
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function(){
        var self = this;
        this.timeoutObj = setTimeout(function(){
            //这里发送一个心跳,后端收到后,返回一个心跳消息,
            //onmessage拿到返回的心跳就说明连接正常
        	websocket.send("ping");
            //console.log("ping!")
            self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
            	websocket.close();     //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    }
}

//加入在线列表
function online(){
	//if (window.WebSocket) {
		//websocket = new WebSocket(encodeURI('wss://'+oladress)); //oladress在main.jsp页面定义
		/*setInterval(function(){
			websocket.send('[checkConnect]'+user);
		},60000);*/
		websocket.onopen = function() {
			//连接成功
			heartCheck.reset().start();      //心跳检测重置
			websocket.send('[join]'+user);
		};
		websocket.onerror = function() {
			//连接失败
			reconnect(url);
		};
		websocket.onclose = function() {
			//连接断开
			reconnect(url);
		};
		//消息接收
		websocket.onmessage = function(message) {
			heartCheck.reset().start();
			if(message.data == 'ping'){
				return;
			}
			var message = JSON.parse(message.data);
			if(message.type == 'goOut'){
				$("body").html("");
				goOut("1");
			}else if(message.type == 'thegoout'){
//				$("body").html("");
//				goOut("2");
				return;
			}else if(message.type == 'senFhsms'){
				fhsmsCount = Number(fhsmsCount)+1;
				$("#fhsmsCount").html(Number(fhsmsCount));
				$("#fhsmsobj").html('<audio style="display: none;" id="fhsmstsy" src="static/sound/'+TFHsmsSound+'.mp3" autoplay controls></audio>');
				$("#fhsmstss").tips({
					side:3,
		            msg:'您有新消息',
		            bg:'#AE81FF',
		            time:30
		        });
			}else if(message.type == 'fhtask'){
				if(message.RNUMBER == 'no'){
					$("#fhsmsobj").html('<audio style="display: none;" id="fhsmstsy" src="static/sound/'+TFHsmsSound+'.mp3" autoplay controls></audio>');
					topTask();//刷新顶部待办任务列表
				}else{
					$.ajax({
						type: "POST",
						url: locat+'/head/isNowRole.do',
				    	data: {RNUMBER:message.RNUMBER,tm:new Date().getTime()},
						dataType:'json',
						cache: false,
						success: function(data){
							 if('yes' == data.msg){
								$("#fhsmsobj").html('<audio style="display: none;" id="fhsmstsy" src="static/sound/'+TFHsmsSound+'.mp3" autoplay controls></audio>');
								topTask();//刷新顶部待办任务列表
							 }
						}
					});
				}
			}
		};
	//}
}
package com.fh.plugin.websocketOnline;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

import net.sf.json.JSONObject;

import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

/**
 * 在线管理
 */
public class OnlineChatServer extends WebSocketServer{

	public OnlineChatServer(int port) throws UnknownHostException {
		super(new InetSocketAddress(port));
	}

	public OnlineChatServer(InetSocketAddress address) {
		super(address);
	}

	/**
	 * 触发连接事件
	 */
	@Override
	public void onOpen( WebSocket conn, ClientHandshake handshake ) {
		//this.sendToAll( "new connection: " + handshake.getResourceDescriptor() );
		//System.out.println("===" + conn.getRemoteSocketAddress().getAddress().getHostAddress());
	}

	/**
	 * 触发关闭事件
	 */
	@Override
	public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
		userLeave(conn);
	}

	/**
	 * 客户端发送消息到服务器时触发事件
	 */
	@Override
	public void onMessage(WebSocket conn, String message){
		message = message.toString();
		if(null != message && message.startsWith("[join]")){
			this.userjoin(message.replaceFirst("\\[join\\]", ""),conn);
		}else if(null != message && message.startsWith("[goOut]")){
			this.goOut(message.replaceFirst("\\[goOut\\]", ""));
		}else if(null != message && message.startsWith("[fhsms]")){
			this.senFhsms(message.replaceFirst("\\[fhsms\\]", ""));
		}else if(null != message && message.startsWith("[fhtask]")){
			this.senFhTask(message.replaceFirst("\\[fhtask\\]", ""));
		}else if(null != message && message.startsWith("[leave]")){
			this.userLeave(conn);
		}else if(null != message && message.startsWith("[count]")){
			this.getUserCount(conn);
		}else if(null != message && message.startsWith("[ConnectionSuccess]")){
			OnlineChatServerPool.setFhadmin(conn);
			this.getUserList();
		}else if(null != message && message.equals("ping")) {
			//心跳检测,无需返回
		}else{
			OnlineChatServerPool.sendMessageToUser(conn, message);//同时向本人发送消息
		}
	}

	public void onFragment( WebSocket conn, Framedata fragment ) {
	}

	/**
	 * 触发异常事件
	 */
	@Override
	public void onError( WebSocket conn, Exception ex ) {
		//ex.printStackTrace();
		if( conn != null ) {
			//some errors like port binding failed may not be assignable to a specific websocket
		}
	}

	/**
	 * 用户加入处理
	 * @param user
	 */
	public void userjoin(String user, WebSocket conn){
		onlineMaganger(1,user,conn);
	}
	
	/**
	 * 站内信通知
	 * @param user
	 */
	public void senFhsms(String user){
		JSONObject result = new JSONObject();
		result.element("type", "senFhsms");
		OnlineChatServerPool.sendMessageToUser(OnlineChatServerPool.getWebSocketByUser(user),result.toString());	
	}
	
	/**
	 * 新任务通知
	 * @param user
	 */
	public void senFhTask(String user){
		JSONObject result = new JSONObject();
		result.element("type", "fhtask");
		WebSocket ws = OnlineChatServerPool.getWebSocketByUser(user);
		if(null != ws){
			result.element("RNUMBER", "no");
			OnlineChatServerPool.sendMessageToUser(ws,result.toString());	//当待办人是具体的人时发给其任务通知
		}else{
			result.element("RNUMBER", user);
			OnlineChatServerPool.sendMessage(result.toString());			//当待办人不在线或者是角色时发给所有在线用户,客户端去过滤出拥有其角色的用户,从而获的新任务通知
		}
	}
	
	/**
	 * 强制某用户下线
	 * @param user
	 */
	public void goOut(String user){
		this.goOut(OnlineChatServerPool.getWebSocketByUser(user),"thegoout");	
	}
	
	/**
	 * 强制用户下线
	 * @param conn
	 */
	public void goOut(WebSocket conn,String type){
		JSONObject result = new JSONObject();
		result.element("type", type);
		result.element("msg", "goOut");
		OnlineChatServerPool.sendMessageToUser(conn,result.toString());	
	}
	
	/**
	 * 用户下线处理
	 * @param user
	 */
	public void userLeave(WebSocket conn){
		onlineMaganger(2,null,conn);
	}

	/**
	 * 获取在线总数
	 * @param user
	 */
	public void getUserCount(WebSocket conn){
		JSONObject result = new JSONObject();
		result.element("type", "count");
		result.element("msg", OnlineChatServerPool.getUserCount());
		OnlineChatServerPool.sendMessageToUser(conn,result.toString());					
	}
	
	/**
	 * 获取在线用户列表
	 * @param user
	 */
	public void getUserList(){
		WebSocket conn =  OnlineChatServerPool.getFhadmin();
		if(null == conn){return;}
		JSONObject result = new JSONObject();
		result.element("type", "userlist");
		result.element("list", OnlineChatServerPool.getOnlineUser());
		OnlineChatServerPool.sendMessageToUser(conn,result.toString());					
	}
	
	/**用户上下线管理
	 * @param type 1:上线;2:下线
	 * @param user
	 * @param conn
	 */
	public synchronized void onlineMaganger(int type,String user, WebSocket conn){
		if(type == 1){
			if(null == OnlineChatServerPool.getWebSocketByUser(user)){		//判断用户是否在其它终端登录
				OnlineChatServerPool.addUser(user,conn);					//向连接池添加当前的连接对象
				addUserToFhadmin(user);
			}else{
				//goOut(conn,"goOut"); //不能重复登录
				
				/* 挤掉对方 */
//				goOut(user);		
				OnlineChatServerPool.addUser(user,conn);					
				addUserToFhadmin(user);
			}
		}else{
			OnlineChatServerPool.removeUser(conn);							//在连接池中移除连接
			this.getUserList();
		}
	}
	
	/**
	 * 有用户登录系统,加入在线列表
	 * @param conn
	 */
	public void addUserToFhadmin(String user){
		WebSocket conn =  OnlineChatServerPool.getFhadmin();
		if(null == conn){return;}
		JSONObject result = new JSONObject();
		result.element("type", "addUser");
		result.element("user", user);
		OnlineChatServerPool.sendMessageToUser(conn,result.toString());	
	}
	
	public static void main( String[] args ) throws InterruptedException , IOException {
		WebSocketImpl.DEBUG = false;
		int port = 8887; //端口
		OnlineChatServer s = new OnlineChatServer(port);
		s.start();
		//System.out.println( "服务器的端口" + s.getPort() );
	}

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值