springboot+sse 发送信息

package com.webstockdemo;


import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

@Slf4j
public class SseEmitterUtil {



    /**
     * 使用 map 对象缓存userId
     */
    private static Map sseEmitterMap = new ConcurrentHashMap<>();

    /**
     * 
     *  创建连接
     * @param userId 用户ID
     * @return SseEmitter
     */
    public static SseEmitter connect(String userId) {
        // 设置超时时间,0表示不过期。默认30秒,超过时间未完成会抛出异常:AsyncRequestTimeoutException
        SseEmitter sseEmitter = new SseEmitter(1L);
        // 注册回调
        sseEmitter.onCompletion(completionCallBack(userId));
        sseEmitter.onError(errorCallBack(userId));
        sseEmitter.onTimeout(timeoutCallBack(userId));

        // 缓存
        sseEmitterMap.put(userId, sseEmitter);


        log.info("创建新的sse连接,当前用户:{}", userId);
        return sseEmitter;
    }
    /**
     * 移除用户连接
     */
    public static void removeUser(String userId) {
        sseEmitterMap.remove(userId);
        log.info("移除用户:{}", userId);
    }
    private static Runnable completionCallBack(String userId) {
        return () -> {
            log.info("结束连接:{}", userId);
            removeUser(userId);
        };
    }
    private static Runnable timeoutCallBack(String userId) {
        return () -> {
            log.info("连接超时:{}", userId);
            removeUser(userId);
        };
    }
    private static Consumer errorCallBack(String userId) {
        return throwable -> {
            log.info("连接异常:{}", userId);
            removeUser(userId);
        };
    }
}

package com.webstockdemo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.Random;

@RestController
@Slf4j
public class WebStockController {

    /**
     * 用于创建连接
     */
    @CrossOrigin
    @GetMapping("/sse/connect/{userId}")
    public SseEmitter connect(@PathVariable String userId) throws IOException {
        SseEmitter connect = SseEmitterUtil.connect(userId);
        connect.send(new Random().nextInt());
        return connect;
    }


    /**
     * 关闭连接
     */
    @CrossOrigin
    @GetMapping("/sse/close/{userid}")
    public String close(@PathVariable("userid") String userid) {
        SseEmitterUtil.removeUser(userid);
        return "连接关闭";
    }

}

jsp 页面代码




    
    消息推送


    

效果

springboot+sse 发送信息_第1张图片

springboot+sse 发送信息_第2张图片 

 

你可能感兴趣的:(java,servlet,spring)