diff --git a/README.md b/README.md index 5b0b400..cae58b0 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,8 @@ 5 [SpringBoot使用WebSocket](https://blog.csdn.net/weixin_44185837/article/details/124942482) -[【ServerSentEvents】服务端单向消息推送](http://www.manongjc.com/detail/40-envenmxrmjsschv.html) \ No newline at end of file +[【ServerSentEvents】服务端单向消息推送](https://www.cnblogs.com/mindzone/p/16877161.html) + +[java实现web实时消息推送的七种方案--个人学习记录](https://blog.csdn.net/weixin_44705301/article/details/128670957) + + diff --git a/src/main/java/com/xtong/zhbs/controller/PassFlowController.java b/src/main/java/com/xtong/zhbs/controller/PassFlowController.java index ccc3bb2..f571ba7 100644 --- a/src/main/java/com/xtong/zhbs/controller/PassFlowController.java +++ b/src/main/java/com/xtong/zhbs/controller/PassFlowController.java @@ -3,37 +3,36 @@ package com.xtong.zhbs.controller; import com.alibaba.fastjson.JSONObject; import com.xtong.zhbs.bean.PassengerFlow; import com.xtong.zhbs.service.PassengerFlowService; +import com.xtong.zhbs.service.SeverSentEventService; import com.xtong.zhbs.utils.AjaxResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import javax.annotation.Resource; import java.util.List; +import java.util.Map; /** * 实时客流 */ @Api(tags = "客流趋势") -@Controller +@RestController @RequestMapping(value = "/real/") public class PassFlowController { + @Resource + private SeverSentEventService severSentEventService; + @Autowired private PassengerFlowService passengerFlowService; @ApiImplicitParam(name = "page",value = "姓名",required = true) @ApiOperation(value = "客流列表") @GetMapping(value = "/psflist") - @ResponseBody public JSONObject psflist(@RequestParam String page, @RequestParam("limit") String limit){ int ipage = 1; int ilimit=10; @@ -42,25 +41,43 @@ public class PassFlowController { } /** - * 数据流方式输出内容 - * @param response - * @return - * @throws IOException + * web连接的SSE目标地址, 保管凭证并返回这个会话资源给web,注意produces属性必须是文本事件流形式 + * 凭证可以使用@PathVariable或者Url参数获取 + * /approve/sse/message + * @param token + * @return SseEmitter + * @author cloud9 + * @date 2022/11/10 09:57 + * */ - @ResponseBody - @RequestMapping(value = "/getMsg", produces="text/event-stream;charset=UTF-8") - DeferredResult getMsg(HttpServletResponse response) throws IOException { - response.setContentType("text/event-stream"); - response.setCharacterEncoding("UTF-8"); - response.setStatus(200); - List passengerFlowList = passengerFlowService.getPassengerFlowList(1,10); -// msgService.removeErrorResponse(); -// msgService.getListRes().add(response); - if(!response.getWriter().checkError()){ - response.getWriter().write("data:hello\n\n"); - response.getWriter().flush(); - } - DeferredResult df = new DeferredResult(60000l); - return df; + @GetMapping(value = "/sse/message", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public SseEmitter message(@RequestParam("clientToken") String token) { + return severSentEventService.createConnection(token); } + + @GetMapping(value = "/boardcast") + public JSONObject boardCast(){ + String message="this is your Dad!!"; +// SseEmitter.SseEventBuilder builder = SseEmitter +// .event() +// .data(message); + severSentEventService.sendMessageToClient(message); + return AjaxResult.renderMsg("ookk"); + } + + /** + * 提供给POSTMAN测试调用,方便给web发送消息调试 + * /approve/sse/message/send + * @param map + * @author cloud9 + * @date 2022/11/10 10:25 + * + */ + @PostMapping("/sse/message/send") + public void send(@RequestBody Map map) { + String client = map.get("client"); + String txt = map.get("txt"); + severSentEventService.sendMessageToClient(client, txt); + } + } diff --git a/src/main/java/com/xtong/zhbs/service/SeverSentEventService.java b/src/main/java/com/xtong/zhbs/service/SeverSentEventService.java index abeb92b..5524eca 100644 --- a/src/main/java/com/xtong/zhbs/service/SeverSentEventService.java +++ b/src/main/java/com/xtong/zhbs/service/SeverSentEventService.java @@ -23,7 +23,8 @@ public class SeverSentEventService { /** * 连接超时时限1小时 (客户端不活跃的时长上限?) */ - private static final Long TIME_OUT = 1000L * 60L * 60L; + private static final Long TIME_OUT = 3600L; +// private static final Long TIME_OUT = 1000L * 60L * 60L; /** * 根据客户端标识创建SSE连接 diff --git a/src/main/java/com/xtong/zhbs/utils/AjaxResult.java b/src/main/java/com/xtong/zhbs/utils/AjaxResult.java index b36c991..a81c1d5 100644 --- a/src/main/java/com/xtong/zhbs/utils/AjaxResult.java +++ b/src/main/java/com/xtong/zhbs/utils/AjaxResult.java @@ -40,6 +40,12 @@ public class AjaxResult { return result; } + public static JSONObject renderMsg(String msg){ + JSONObject result = new JSONObject(); + result.put("code",200); + result.put("msg",msg); + return result; + } /** * 异常信息 * @param msg