websocket初接触

首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。

使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。

虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。

1.new一个websocket的类,里面的字段可以自己定义,前台需要什么可以写在里面使用推送。

public class WebSocketMessage {

	/**
	 * 消息内容
	 */
	private String context;

	private Integer onsiteLearningRecordId;
	/**
	 * 签到通知状态1发生更新0连接成功
	 */
	private Integer state;
    private Integer userId;
    private Integer type;
    private Integer staffType;
    private Integer signType;
		/**
	 * 省略get/set方法
	 */
	}

2.Spring的service层发送、

WebSocketMessage webSocketMessage = new WebSocketMessage();
			webSocketMessage.setOnsiteLearningRecordId(entity.getBusinessPkId());
			webSocketMessage.setState(1);
			webSocketMessage.setType(entity.getEventTye());
			webSocketMessage.setStaffType(entity.getStaffType());
			webSocketMessage.setSignType(2);
			try {
				WsServer.sendMessage(webSocketMessage);
			} catch (IOException | EncodeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

3.websocket的类

 @ServerEndpoint(value = "/webSocket/{onisteLearningRecordId}")
    @Component
    public class WsServer {
    //打印日志使用
    private static Logger logger = LoggerFactory.getLogger(WsServer.class);
    	// 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    	private static int onlineCount = 0;
    	// concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    
    	private static CopyOnWriteArraySet<WsServer> webSocketSet = new CopyOnWriteArraySet<WsServer>();
	// 与某个客户端的连接会话,需要通过它来给客户端发送数据
	private Session session;

    //根据这个id来判定
	private int onsiteLearningRecordId;
	/**
 * 连接建立成功调用的方法
 * 
 * @throws EncodeException
 */
@OnOpen
public void onOpen(Session session, @PathParam(value = "onisteLearningRecordId") int onsiteLearningRecordId)
		throws EncodeException {
	this.session = session;
	this.onsiteLearningRecordId = onsiteLearningRecordId;
	webSocketSet.add(this); // 加入set中
	try {
		WebSocketMessage webSocketMessage = new WebSocketMessage();
		webSocketMessage.setContext("连接成功");
		webSocketMessage.setState(0);
		sendOpenMessage(webSocketMessage);
	} catch (IOException e) {
		logger.error("websocket IO异常");
	}
}
/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose() {
		webSocketSet.remove(this); // 从set中删除
		subOnlineCount(); // 在线数减1
		logger.info("有一连接关闭!当前在线人数为" + getOnlineCount());
	}
/**
	 * 收到客户端消息后调用的方法
	 * 
	 * @param message
	 *            客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
    System.out.println("来自客户端的消息:" + message);

    //群发消息
    for (MyWebSocket item : webSocketSet) {
        try {
            item.sendMessage(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 
 * @param session
 * @param error
 */
@OnError
public void onError(Session session, Throwable error) {
	logger.error("发生错误");
	error.printStackTrace();
}

public static void sendMessage(WebSocketMessage webSocketMessage) throws IOException, EncodeException {
      //webSocketSet是onOpen时websocket连接时就有了
		for (WsServer wsServer : webSocketSet) {
			if (wsServer.onsiteLearningRecordId == webSocketMessage.getOnsiteLearningRecordId()) {
				logger.info("onsite learning staff sign-in:{} ", webSocketMessage);
				String message = JSON.toJSONString(webSocketMessage);
				//发送消息
				wsServer.session.getBasicRemote().sendText(message);
			}
		}
	}
public void sendOpenMessage(WebSocketMessage webSocketMessage) throws IOException, EncodeException {
	String message = JSON.toJSONString(webSocketMessage);
	this.session.getBasicRemote().sendText(message);
}

/**
 * 群发自定义消息
 */
public static void sendInfo(String message) throws IOException {
 for (MyWebSocket item : webSocketSet) {
        try {
            item.sendMessage(message);
        } catch (IOException e) {
            continue;
        }
    }
}

public static synchronized int getOnlineCount() {
	return onlineCount;
}

public static synchronized void addOnlineCount() {
	WsServer.onlineCount++;
}

public static synchronized void subOnlineCount() {
	WsServer.onlineCount--;
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值