activiti websocket推送任务一

为什么使用websocket推送任务

一般现在服务器端有数据变化,我们采用的是定时拉去的方式,这种方式在一般数据量的时候还是可以接受的,但是对于数据量很大就不太合适了,websocket就是采取一种推的方式把任务推送给浏览器,具体websocket详细,请查询相关文档。这里就不过多阐述了,我们还是一步步的来完成我们如何实现待办任务的实时推送功能吧。

  • 1. 引入pom
<!-- 使用spring websocket依赖的jar包 -->
<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>
 <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.5.4</version>
 </dependency>
  • 2. 配置websocket
@Configuration
@EnableWebSocket
public class SpringWebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler(), "/socket/task").setAllowedOrigins("*").addInterceptors(new SpringWebSocketHandlerInterceptor());
    }

    @Bean
    public TaskWebSocketHandler webSocketHandler() {
        return new TaskWebSocketHandler();
    }

}
  • 3. 编写handler
@Component
public class TaskWebSocketHandler extends TextWebSocketHandler {

    @Autowired
    private IWebSocketService webSocketService;


    /**
     * 当客户连接的时候触发
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //获取当前的用户id
        String userid = (String) session.getAttributes().get(SpringWebSocketHandlerInterceptor.WEBSOCKET_USERID);
        //添加到自己的缓存中去
        webSocketService.addSession(userid, session);
        //发送当前用户的任务列表给客户端
        webSocketService.sendMessage(userid);
    }


    /**
     * 当连接断开的时候触发
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        //获取当前的userId
        String userid = (String) session.getAttributes().get(SpringWebSocketHandlerInterceptor.WEBSOCKET_USERID);
        if(null != userid){
            //移除session
            webSocketService.removeSession(userid);
        }
    }

    /**
     * 当出错的时候触发
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String userid = (String) session.getAttributes().get(SpringWebSocketHandlerInterceptor.WEBSOCKET_USERID);
        if (session.isOpen()) {
            //关闭通道
            session.close();
        }
        //移除通道
        webSocketService.removeSession(userid);
    }

}
  • 4. 编写HttpSessionHandshakeInterceptor
/**
 * websocket拦截器
 */
public class SpringWebSocketHandlerInterceptor  extends HttpSessionHandshakeInterceptor {

    public static final String WEBSOCKET_USERID = "websocket_userid";

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            //获取当前session
            HttpSession session = servletRequest.getServletRequest().getSession(false);
            if (session != null) {
                //获取当前登录用户
                User user = (User) session.getAttribute(UserUtil.USER);
                if (user==null) {
                    return  false;
                }
                //把用户的id放入websocket通道属性里
                attributes.put(WEBSOCKET_USERID,user.getId());
            }
        }
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception ex) {
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
  • 5. 编写js
/**
 * websocket 消息推送
 * @type {{ws: null, init: sckt.init, closeSocket: sckt.closeSocket, showMsgBox: sckt.showMsgBox, genMsgHtml: sckt.genMsgHtml}}
 */
var sckt= {
    ws:null,
    init:function () {
        var _this = this;
        this.ws = $.websocket({
            domain: window.location.hostname,
            port: window.location.port,
            protocol: ctx + "/socket/task;jsessionid="+jsessionid,
            onOpen: function (e) {
                // console.log("WebSocket连接成功");
            },
            onError: function (e) {
                // console.log("WebSocket连接错误");
            },
            onMessage: function (res) {
                if(res){
                    _this.msgObj = JSON.parse(res);
                    _this.showMsgBox();
                }
            },
            onClose: function (e) {
                // console.log("WebSocket连接关闭");
            }
        });

        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常.
        window.onbeforeunload = function () {
            _this.closeSocket();
        };
    },

    // 关闭连接
    closeSocket:function(){
        if (this.ws.socket == null || this.ws.socket.readyState == 2 || this.ws.socket.readyState == 3) {
            return true;
        }
        this.ws.close();
    },

    // 显示消息框
    showMsgBox:function(){
        var _this = this;
        if(!_this.msgBox){
            _this.msgBox = $("<div class=\"msg-box\" id=\"jsMsgBox\"></div>");
            _this.msgBox.appendTo($('body'));
            _this.msgBox.dialog({
                dialogClass: "no-close",
                title:'消息提醒<i class="msg-total" id="jsMsgTotal">0</i>',
                position: { my: "right bottom", at: "right bottom",of: window ,collision: "fit"},
                resizable: false,
                draggable:false,
                maxHeight:600,
                open: function (event, ui) {
                    var that = this;
                    $(".ui-dialog-titlebar-close", $(this).parent()).html('<span class="ui-icon ui-icon ui-icon-carat-1-s"></span>');
                    $(".ui-dialog-titlebar-close", $(this).parent()).unbind('click').bind('click',function (e) {
                        $(".ui-dialog-content", $(that).parent()).toggleClass('dialog-content-hide');
                        $(".ui-icon", $(this).parent()).toggleClass('ui-icon-carat-1-s');
                        _this.msgBox.dialog({position: { my: "right bottom", at: "right bottom",of: window ,collision: "fit"}});
                    });
                }
            });
            _this.msgBox.dialog('close');
        }
        if(_this.msgObj){
            if(!_this.msgBox.dialog('isOpen')){
                _this.msgBox.dialog('open');
            }
            _this.msgBox.dialog({'title': '消息提醒<i class="msg-total" id="jsMsgTotal">'+_this.msgObj.total+'</i>'});
            _this.msgBox.html(_this.genMsgHtml());
        }
    },

    /**
     * 将返回的内容组装成html
     * @returns {string}
     */
    genMsgHtml:function(){
        var _this = this, html = '<ul>';
        if(_this.msgObj.datas){
            var arr = _this.msgObj.datas;
            for(var i = 0; i<arr.length; i++){
                html+='<li id="taskId_"+'+arr[i].taskId+'>'+arr[i].taskName+'</li>';
            }
        }
        html+='</ul>';
        return html;
    }
};
  • 6. 编写jsp
<%@ include file="/common/global.jsp"%>
    <%
        String rootPath = request.getContextPath();
        String jsessionid = request.getSession().getId();
    %>
    <script>
        var notLogon = ${empty user};
        if (notLogon) {
            location.href = '${ctx}/login?timeout=true';
        }
        var rootPath = "<%=rootPath%>";
        var jsessionid = "<%=jsessionid%>";
        var WEB_SOCKET_DEBUG = false;
        var WEB_SOCKET_SWF_LOCATION = rootPath + '/js/common/plugins/websocket/WebSocketMain.swf';
    </script>

效果如下:

右下角的弹出

今天先写到这里,明天在写IWebSocketService的实现和配置全局监听

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小学生05101

flowable

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值