package com.web.jhsop.websocket.util; import com.web.jhsop.websocket.config.WebSocketConfig; import com.web.jhsop.websocket.dao.SopDeviceDao; import com.web.jhsop.websocket.dao.SopFileDao; import com.web.jhsop.websocket.entity.SopDevice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.websocket.*; import javax.websocket.server.PathParam; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @ConditionalOnClass(value = WebSocketConfig.class) @Component //开发时候注释,打包时放出来 //@ServerEndpoint("/websocket/{deviceId}") // 接口路径 ws://localhost:9999/webSocket/deviceId; public class WebSocketUtil { protected Logger logger = LoggerFactory.getLogger(this.getClass()); private static SopDeviceDao sopDeviceDao; private static SopFileDao sopFileDao; @Autowired public void setSopDeviceDao(SopDeviceDao sopDeviceDao){ WebSocketUtil.sopDeviceDao = sopDeviceDao; } @Autowired public void setSopFileDao(SopFileDao sopFileDao){ WebSocketUtil.sopFileDao = sopFileDao; } //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; /** * 设备ID */ private String deviceId; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 //虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。 // 注:底下WebSocket是当前类名 private static CopyOnWriteArraySet webSockets =new CopyOnWriteArraySet<>(); // 用来存在线连接用户信息 private static ConcurrentHashMap sessionPool = new ConcurrentHashMap(); /** * 链接成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam(value="deviceId")String deviceId) { try { if(StringUtils.isEmpty(deviceId)||deviceId.equals("undefined")){ return; } if(deviceId.length() <= 12){ //12位组成 则为设备唯一码 否则则是翻页功能中发起的socket连接 List list = sopDeviceDao.findByBsDevice(deviceId); if(CollectionUtils.isEmpty(list)){ SopDevice sopDevice = new SopDevice(); sopDevice.setBsDevice(deviceId); sopDevice.setCreatedTime(new Date()); sopDeviceDao.save(sopDevice); } } this.session = session; this.deviceId = deviceId; webSockets.add(this); sessionPool.put(deviceId, session); logger.info("【websocket消息】有新的连接,总数为:"+webSockets.size()); } catch (Exception e) { } } /** * 链接关闭调用的方法 */ @OnClose public void onClose() { try { webSockets.remove(this); sessionPool.remove(this.deviceId); logger.info("【websocket消息】连接断开,总数为:"+webSockets.size()); } catch (Exception e) { } } /** * 收到客户端消息后调用的方法 * * @param message */ @OnMessage public void onMessage(String message) { logger.info("【websocket消息】收到客户端消息:"+message); } /** 发送错误时的处理 * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { logger.error("用户错误,原因:"+error.getMessage()); error.printStackTrace(); } // 此为广播消息 public void sendAllMessage(String message) { logger.info("【websocket消息】广播消息:"+message); for(WebSocketUtil webSocket : webSockets) { try { if(webSocket.session.isOpen()) { webSocket.session.getAsyncRemote().sendText(message); } } catch (Exception e) { e.printStackTrace(); } } } // 此为单点消息 public void sendOneMessage(String deviceId, String message) { Session session = sessionPool.get(deviceId); if (session != null&&session.isOpen()) { try { logger.info("【websocket消息】 单点消息:"+message); session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } // 此为单点消息 public void sendOneObject(String deviceId, Object object) { Session session = sessionPool.get(deviceId); if (session != null&&session.isOpen()) { try { logger.info("【websocket消息】 单点消息(对象):"+object); session.getAsyncRemote().sendObject(object); } catch (Exception e) { e.printStackTrace(); } } } // 此为单点消息(多人) public void sendMoreMessage(String[] deviceIds, String message) { for(String deviceId:deviceIds) { Session session = sessionPool.get(deviceId); if (session != null&&session.isOpen()) { try { logger.info("【websocket消息】 单点消息:"+message); session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } } }