leQIogPwCB

package com.ysu.gdp.web;
 
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
 
import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
 
 
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
 
import com.alibaba.fastjson.JSONObject;
 
@ServerEndpoint("/websocket/{user_id}")
@Component
 
public class WebSocketServer {
 
    private static int onlineCount = 0;
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
 
    private Session session;
    private String user_id="";// 账号id
    
    @OnOpen
    public void onOpen(Session session,@PathParam("user_id") String user_id) {
        this.session = session;
        webSocketSet.add(this);
        addOnlineCount();
        this.user_id=user_id;
        System.out.println("user_id="+user_id+"的用户和服务器建立了连接");
    }
 
 
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        subOnlineCount(); 
        System.out.println("user_id="+user_id+"的用户和服务器断开了连接");
    }
 
 
    @OnMessage
    public void onMessage(String message, Session session) {
        //log.info("收到来自窗口"+sid+"的信息:"+message);
    	boolean ijo=isJsonObject(message);//避免message不可转为json时,后台打印大量不必要的异常日志
    	if(ijo) {
       	 JSONObject message2 = JSONObject.parseObject(message);
       	 if(message2!=null) {
       		 Object uuid=message2.get("uuid");
   	    	 if(uuid!=null) {
   	    		 System.out.println("收到uuid为:"+uuid.toString()+" 的消息反馈,即将终止发送");
   	    		 Thread t=findThread(uuid.toString());
   	    		 if(t!=null) {
   	    			 t.interrupt();
   	    			 System.out.println("uuid为:"+uuid.toString()+" 的消息终止发送成功");
   	    		 }else{
   	    			 System.out.println("未找到uuid为:"+uuid.toString()+" 的消息发送线程");
   	    		 }
   	    	 }else{
   	    		 System.out.println("反馈数据中不含uuid");
   	    	 }
       	 }
    	}    	
    }
    /**
     * 判断字符串是否可以转化为json对象
     * @param content
     * @return
     */
     public static boolean isJsonObject(String content) {
         // 此处应该注意,不要使用StringUtils.isEmpty(),因为当content为"  "空格字符串时,JSONObject.parseObject可以解析成功,
         // 实际上,这是没有什么意义的。所以content应该是非空白字符串且不为空,判断是否是JSON数组也是相同的情况。
         if(StringUtils.isBlank(content))
             return false;
         try {
             JSONObject jsonStr = JSONObject.parseObject(content);
             return true;
         } catch (Exception e) {
             return false;
         }
     }
 
    @OnError
    public void onError(Session session, Throwable error) {
        //log.error("发生错误");
        error.printStackTrace();
    }
 
    public void sendMessage(String message) throws IOException {
        //this.session.getBasicRemote().sendText(message);
    	String uuid = UUID.randomUUID().toString().replaceAll("-","");
    	Thread myThread = new Thread(new Runnable() {
    		public void run() {
    			int i=1;
    			try {
    				 JSONObject message2 = JSONObject.parseObject(message);
       				 message2.put("uuid", uuid);
    				 while (!Thread.currentThread().isInterrupted()) {
    					 System.out.println("正在发送uuid为:"+uuid+" 的消息,次数:第"+i+"次");
    					 i++;
	       				 session.getBasicRemote().sendText(JSONObject.toJSONString(message2));    				
	       				 Thread.sleep(3000);
	       				 if(i>100) {
	       					System.out.println("用户:"+user_id+"持续5分钟未发送反馈,终止本次消息传递");
	       					break;
	       				 }
    				}
    			} catch (Exception e) {//interrupt一个线程时sleep会抛异常,都打印的话日志太多了
    				//e.printStackTrace();
    			}
    		}
    	}, uuid);
    	myThread.start(); 
    }
    /**
     * 通过线程组获得线程
     *
     * @param threadName
     * @return
     */
    public static Thread findThread(String threadName) {
        ThreadGroup group = Thread.currentThread().getThreadGroup();
        while(group != null) {
            Thread[] threads = new Thread[(int)(group.activeCount() * 1.2)];
            int count = group.enumerate(threads, true);
            for(int i = 0; i < count; i++) {
                if(threads[i].getName().equals(threadName)) {
                    return threads[i];
                }
            }
            group = group.getParent();
        }
        return null;
    }
 
 
    public static void sendInfo(Object ob,String message,@PathParam("user_id") String user_id) throws IOException {
        //log.info("推送消息到窗口"+sid+",推送内容:"+message);
    	
        for (WebSocketServer item : webSocketSet) {
   
            try {
                //这里可以设定只推送给这个sid的,为null则全部推送
                if(user_id==null) {
                 if(message!=null) {
                	 synchronized (item) {
                		 item.sendMessage(message);
                	 }
                 }
                  if(ob!=null) {
                	  synchronized (item) {
                		  item.sendMessage(JSONObject.toJSONString(ob));
                	  }
                  }
                }else if(item.user_id.equals(user_id)){
                	if(message!=null) {
                		 synchronized (item) {
                             item.sendMessage(message);                			 
                		 }
                	}
                    if(ob!=null) {
                    	synchronized (item) {
                            item.sendMessage(JSONObject.toJSONString(ob));
                    	}
                    }
                }
            } catch (IOException e) {
                continue;
            }
        }
    }
 
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
 
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
 
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值