利用webSocket进行服务器推送,并发起桌面通知
来源:互联网 发布:java jasperreports 编辑:程序博客网 时间:2024/06/04 19:51
需求:定时读取数据,判断后利用websocket 发送消息给特定用户,并利用html5的Notification 发起桌面通知。
pom.xml 中添加相关Maven依赖:
<!-- websockt--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency>
编写WebSocket相关类。在WebSocketConfig中配置处理器(systemWebSocketHandler)以及拦截器(WebSocketHandshakeInterceptor)
@Configuration@EnableWebMvc@EnableWebSocketpublic class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) { webSocketHandlerRegistry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()); webSocketHandlerRegistry.addHandler(systemWebSocketHandler(),"/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()) .setAllowedOrigins("*").withSockJS(); } @Bean public WebSocketHandler systemWebSocketHandler(){ return new SystemWebSocketHandler(); }}
下面是 SystemWebSocketHandler 的配置
public class SystemWebSocketHandler implements WebSocketHandler { private static final Logger logger; private static final HashSet<WebSocketSession> users; static { users = new HashSet<>(); logger = LoggerFactory.getLogger(SystemWebSocketHandler.class); }// @Autowired// IWebSocketService webSocketService; @Override public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception { users.add(webSocketSession); } @Override public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception { } @Override public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception { if (webSocketSession.isOpen()) { webSocketSession.close(); } logger.debug("websocket连接关闭......"); users.remove(webSocketSession); } @Override public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception { logger.debug("websocket 连接关闭......"); users.remove(webSocketSession); } @Override public boolean supportsPartialMessages() { return false; } /** * 向所有用户推送消息 * * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { try { if (user.isOpen()) {// synchronized(user) { user.sendMessage(message);// } } } catch (IOException e) { e.printStackTrace(); } } } /** * 指定用户推送消息 * * @param roleId * @param message */ public void sendMessageToUser(int roleId, TextMessage message) { for (WebSocketSession user : users) { LoginUser loginUser = (LoginUser) user.getAttributes().get("user"); if (loginUser.getRoleId() == roleId || loginUser.getRoleId() == 0) { try { if (user.isOpen()) { synchronized (loginUser) { user.sendMessage(message); } } } catch (IOException e) { e.printStackTrace(); } break; } } } /** * 查看是否存在未处理的举报 */ public void doTask() { boolean hasinfo = false; /** 逻辑处理代码段 **/ if (hasinfo) { sendMessageToUser(2, new TextMessage("推送内容")); } }}
WebSocketHandshakeInterceptor 的配置(每次建立连接都会进行握手,会被此拦截器拦截)
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { private static Logger logger = LoggerFactory.getLogger(HandshakeInterceptor.class); @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); if (session != null) { //使用userName区分WebSocketHandler,以便定向发送消息 LoginUser user = (LoginUser) session.getAttribute("login"); attributes.put("user",user); } } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { }}
定时进行任务处理
@Scheduled(fixedRate = 1000 * 60 * 60 * 2) // 每隔2小时执行一次 public void scheduleMethod() { new SystemWebSocketHandler().doTask(); }
定时任务的成功执行,需要在配置文件中启动定时器,使@Schedued 生效
<!-- 启动定时器 --> <task:annotation-driven/>
进行到这一步后台的功能基本完成,接下来需要在js 中连接webSocket 并接收消息。
var ip = window.location.host;var websocket; if ('WebSocket' in window) { websocket = new WebSocket("ws://" + ip + "/xxx/webSocketServer"); } else if ('MozWebSocket' in window) { websocket = new MozWebSocket("ws://" + ip + "/xxx/webSocketServer"); } else { websocket = new SockJS("http://" + ip + "/xxx/sockjs/webSocketServer"); } websocket.onopen = function (evnt) { console.info("websocket已连接") }; websocket.onmessage = function (evnt) { console.info("后台传来消息") //发送桌面消息(这里是发送消息相关代码) }; websocket.onerror = function (evnt) { console.info("websocket连接出错") }; websocket.onclose = function (evnt) { console.info("websocket连接已关闭") }
为了实现Notification,首先要检查并申请通知权限
window.addEventListener('load', function () { // 首先,让我们检查我们是否有权限发出通知 // 如果没有,我们就请求获得权限 if (window.Notification && Notification.permission !== "granted") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } }); } })
以下为实现通知部分的逻辑
// 如果用户同意就创建一个通知 if (window.Notification && Notification.permission === "granted") { webnotify() } // 如果用户没有选择是否显示通知 // 注:因为在 Chrome 中我们无法确定 permission 属性是否有值,因此 // 检查该属性的值是否是 "default" 是不安全的。 else if (window.Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } // 如果用户同意了 if (status === "granted") { webnotify() } // 否则,我们可以让步的使用常规模态的 alert else { mynotify() } }); } // 如果用户拒绝接受通知 else { // 我们可以让步的使用常规模态的 alert mynotify() }
mynotify()是自定义的通知实现,此处不贴出实现代码。下面是webnotify()方法的实现。
function webnotify(){ var notify = new Notification( "通知", { dir: 'auto', lang: 'zh-CN', icon: '???.png',//通知的缩略图,//icon 支持ico、png、jpg、jpeg格式 body: "" //通知的具体内容 } ); notify.onclick = function () { //如果通知消息被点击,通知窗口将被激活 window.focus(); window.open("http://?");//打开指定url notify.close(); }, notify.onerror = function () { console.log("HTML5桌面消息出错!!!"); }; notify.onshow = function () { setTimeout(function () { notify.close(); }, 20000) }; notify.onclose = function () { console.log("HTML5桌面消息关闭!!!"); }; }
至此需求已初步实现,细节处可以慢慢修改。
0 0
- 利用webSocket进行服务器推送,并发起桌面通知
- 服务器实时通知客户端方案,服务器发送/推送事件方案(1)websocket
- IOS服务器推送通知
- 使用WebSocket推送服务器消息
- 一步步实现服务器推送通知
- 利用websocket实现android消息推送
- html5利用websocket完成的推送功能
- html5利用websocket完成的推送功能
- 利用websocket实现安卓消息推送
- html5利用websocket完成的推送功能
- 【Vertx】利用vertx实现websocket数据推送
- android利用WebSocket实现消息推送
- springboot+websocket+sockjs进行消息推送
- HTML5中的服务器‘推送’技术 -WebSocket
- HTML5中的服务器‘推送’技术 -WebSocket
- 利用信鸽推送提示评论通知
- 利用socket进行消息推送
- 极光后台服务器推送消息通知
- tomcat配置https以及nginx使用ssl模块配置HTTPS
- windows+VS2013+CUDA7.5配置
- Windows多线程指南
- oracle数据库作业
- cef3 学习总结
- 利用webSocket进行服务器推送,并发起桌面通知
- Android图片压缩(质量压缩和尺寸压缩)&Bitmap转成字符串上传
- weblogic的默认端口是7001
- 我与python约个会:02开发环境搭建~安装python3
- ubuntu日志文件介绍
- 基于stm32cube的stm32系列不定长度串口接收(IDLE接收)
- 行为型模式之解释器模式(Interpreter)
- TI C2000 MCU Boot过程分析-以TMS320F28069为例
- 170514 逆向-IDC脚本一例