Spring整合websocket整合應用示例(下)
在Spring整合websocket整合應用示例(上)文章中,我們已經(jīng)實現(xiàn)了websocket,但還有一個核心的業(yè)務實現(xiàn)類沒有實現(xiàn),這里我們就實現(xiàn)這個業(yè)務核心類,因為老夫參與的這個系統(tǒng)使用websocket發(fā)送消息,所以其實現(xiàn)就是如何發(fā)送消息了。
7. NewsListenerImpl的實現(xiàn)
package cn.bridgeli.websocket; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.lagou.common.base.util.date.DateUtil; import com.lagou.platform.news.api.enumeration.PlatNewsCategoryType; import com.lagou.platform.news.web.dao.ext.model.PlatNewsVo; import com.lagou.platform.news.web.dao.ext.model.SearchCondition; import com.lagou.platform.news.web.quartz.impl.TimingJob; import com.lagou.platform.news.web.service.PlatNewsService; import org.apache.commons.lang.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.socket.TextMessage; import java.io.IOException; import java.util.Date; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @Description : 站內消息監(jiān)聽器實現(xiàn) * @Date : 16-3-7 */ @Component public class NewsListenerImpl implements NewsListener{ private static final Logger logger = LoggerFactory.getLogger(NewsListenerImpl.class); Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); //線程池 private ExecutorService executorService = Executors.newCachedThreadPool(); //任務調度 private SchedulerFactory sf = new StdSchedulerFactory(); @Autowired private PlatNewsService platNewsService; @Override public void afterPersist(PlatNewsVo platNewsVo) { logger.info("監(jiān)聽到有新消息添加。。。"); logger.info("新消息為:"+gson.toJson(platNewsVo)); //啟動線程 if(null != platNewsVo && !StringUtils.isBlank(platNewsVo.getCurrentoperatoremail())){ //如果是定時消息 if(platNewsVo.getNewsType() == PlatNewsCategoryType.TIMING_TIME.getCategoryId()){ startTimingTask(platNewsVo); //定時推送 }else{ //立即推送 executorService.execute(new AfterConnectionEstablishedTask(platNewsVo.getCurrentoperatoremail())); } } } @Override public void afterConnectionEstablished(String email) { logger.info("建立websocket連接后推送新消息。。。"); if(!StringUtils.isBlank(email)){ executorService.execute(new AfterConnectionEstablishedTask(email)); } } /** * @Description : 如果新添加了定時消息,啟動定時消息任務 * @param platNewsVo */ private void startTimingTask(PlatNewsVo platNewsVo){ logger.info("開始定時推送消息任務。。。"); Date timingTime = platNewsVo.getTimingTime(); if(null == timingTime){ logger.info("定時消息時間為null。"); return; } logger.info("定時推送任務時間為:"+DateUtil.date2String(timingTime)); JobDetail jobDetail= JobBuilder.newJob(TimingJob.class) .withIdentity(platNewsVo.getCurrentoperatoremail()+"定時消息"+platNewsVo.getId(), "站內消息") .build(); //傳遞參數(shù) jobDetail.getJobDataMap().put("platNewsService",platNewsService); jobDetail.getJobDataMap().put("userEmail",platNewsVo.getCurrentoperatoremail()); Trigger trigger= TriggerBuilder .newTrigger() .withIdentity("定時消息觸發(fā)"+platNewsVo.getId(), "站內消息") .startAt(timingTime) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(0) //時間間隔 .withRepeatCount(0) //重復次數(shù) ) .build(); //啟動定時任務 try { Scheduler sched = sf.getScheduler(); sched.scheduleJob(jobDetail,trigger); if(!sched.isShutdown()){ sched.start(); } } catch (SchedulerException e) { logger.info(e.toString()); } logger.info("完成開啟定時推送消息任務。。。"); } /** * @Description : 建立websocket鏈接后的推送線程 */ class AfterConnectionEstablishedTask implements Runnable{ String email ; public AfterConnectionEstablishedTask(String email){ this.email = email; } @Override public void run() { logger.info("開始推送消息給用戶:"+email+"。。。"); if(!StringUtils.isBlank(email)){ SearchCondition searchCondition = new SearchCondition(); searchCondition.setOperatorEmail(email); JSONArray jsonArray = new JSONArray(); for(PlatNewsCategoryType type : PlatNewsCategoryType.values()){ searchCondition.setTypeId(type.getCategoryId()); int count = platNewsService.countPlatNewsByExample(searchCondition); JSONObject object = new JSONObject(); object.put("name",type.name()); object.put("description",type.getDescription()); object.put("count",count); jsonArray.add(object); } if(null != jsonArray && jsonArray.size()>0){ UserSocketVo userSocketVo = WSSessionLocalCache.get(email); TextMessage reMessage = new TextMessage(gson.toJson(jsonArray)); try { if(null != userSocketVo){ //推送消息 userSocketVo.getWebSocketSession().sendMessage(reMessage); //更新推送時間 userSocketVo.setLastSendTime(DateUtil.getNowDate()); logger.info("完成推送新消息給用戶:"+userSocketVo.getUserEmail()+"。。。"); } } catch (IOException e) { logger.error(e.toString()); logger.info("站內消息推送失敗。。。"+e.toString()); } } } logger.info("結束推送消息給"+email+"。。。"); } } }
這個類就是websocket的核心業(yè)務的實現(xiàn),其具體肯定和業(yè)務相關,由于業(yè)務的不同,實現(xiàn)肯定不同,因為老夫參與的系統(tǒng)是發(fā)送消息,所以里面最核心的一句就是:
userSocketVo.getWebSocketSession().sendMessage(reMessage);
通過WebSocketSession的sendMessage方法把我們的消息發(fā)送出去。另外,這主要是后端的實現(xiàn),至于前端的實現(xiàn),因為老夫是后端程序猿比較關注后端,所以前端就不多做介紹了,大家可以自己去網(wǎng)上查資料。最后需要說明的是,老夫之前搜一些學習資料的時候,發(fā)現(xiàn)老夫該同事的寫法和有一篇文章幾乎一樣,我想該同事應該是參考了這篇文章,所以列在下面,算作參考資料。
- Spring WebSocket 404錯誤的解決方法
- Spring和Websocket相結合實現(xiàn)消息的推送
- 完美解決spring websocket自動斷開連接再創(chuàng)建引發(fā)的問題
- java中實現(xiàn)兼容ie6 7 8 9的spring4+websocket
- 詳解WebSocket+spring示例demo(已使用sockJs庫)
- Spring整合WebSocket應用示例(上)
- 詳解在Spring Boot框架下使用WebSocket實現(xiàn)消息推送
- SpringBoot webSocket實現(xiàn)發(fā)送廣播、點對點消息和Android接收
- 詳解spring boot Websocket使用筆記
- Spring集成webSocket頁面訪問404問題的解決方法
相關文章
Java中ArrayList去除重復元素(包括字符串和自定義對象)
本文主要介紹了Java中ArrayList去除重復元素(包括字符串和自定義對象)的方法。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03SpringBoot?@InitBinder注解綁定請求參數(shù)的過程詳解
這篇文章主要介紹了SpringBoot?@InitBinder注解綁定請求參數(shù),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04Java中Collection與Collections的區(qū)別詳解
這篇文章主要為大家詳細介紹了Java中Collection與Collections的區(qū)別,文中有詳細的代碼示例,具有一定的參考價值,感興趣的同學可以參考一下2023-06-06