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--;
}
}
leQIogPwCB
最新推荐文章于 2025-04-25 19:16:38 发布