package cn.iocoder.yudao.module.rescue.app.controller.admin;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;


/**`1
 * @Author: chuxia0811
 * @Date: 2023/7/9 10:21
 * @Description :
 */
@ServerEndpoint(value = "/websocket/announcement/{userId}")
@Component
public class AnnouncementSocket {
    private final static Logger log = LoggerFactory.getLogger(AnnouncementSocket.class);
    // 保存链接的session，key为用户名,value为对应的session名
    public static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
    //关键代码，设置一个静态上下文属性appcontext
    private static ApplicationContext appcontext;
    public static void setAppcontext(ApplicationContext appcontext) {
        AnnouncementSocket.appcontext = appcontext;
    }
    public static ApplicationContext getAppcontext() {
        return appcontext;
    }


    /**
     * 创建连接
     * 用于监听建立连接，当有客户端与该服务端点建立连接时，将会自回调该注解标注的方法
     * @param session
     * @param userId
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        this.sessionMap.put(userId,session);
        log.info("用户{}已创建连接", userId);
    }


    /**
     * 用于监听客户端向服务端发送消息，当客户端与服务端发送消息时，将会回调该注解标注的方法
     * {
     *     Stringitude:124.11,
     *     latitude:125.33,
     *     positionInfo:"山东省济南市市中区八一立交桥"
     * }
     * @param msg
     * @param userId
     */
    @OnMessage
    public void onMessage(String msg,@PathParam(value = "userId") String userId){
        System.out.println("消息通知+"+userId);
    }


    /**
     * 用于监听连接关闭，当客户端与该服务端点断开连接时，将会回调该注解标注的方法
     * @param session
     * @param userId
     */
    @OnClose
    public void onClose(Session session,@PathParam(value = "userId") String userId){
        this.sessionMap.remove(userId);
    }


    /**
     * 用于监听该连接上的任何错误，当客户端与该服务端点的连接发生任何异常，都将回调该注解标注的方法
     * 注意该方法的参数必选Throwable，可选Sessiion以及0-n个String参数，且String参数需要使用@PathParam注解标注
     * @param throwable
     * @param driverId
     */
    @OnError
    public void onError(Throwable throwable,@PathParam(value = "driverId") String driverId){
        log.error("用户{}连接发生异常", driverId);
    }

    /**
     * 发送给指定的用户
     * @param message
     */
    public void sendMessage(String message, String userId) throws IOException {
        if (sessionMap.containsKey(userId)){
            Session session = sessionMap.get(userId);
            session.getAsyncRemote().sendText(message);
        }
    }


}
