JEECG整合WebSocket

1.背景:
最近由于工做须要在倒腾JEECG,JEECG是一款基于代码生成器的快速开发平台,功能是作得挺不错的,可是历史真是有点久远了,使用的框架是SpringMVC+Spring+Hibernate。然而如今早已经是微服务遍地开花的时代。javascript

2.JEECG整合WebSocket的步骤:前端

(1)创建Handlerjava

@Component
public class WebSocketHandler extends AbstractWebSocketHandler {

    private static final ArrayList<WebSocketSession> users;

    private Logger logger = LoggerFactory.getLogger(WebSocketHandler.class);

    static {
        users = new ArrayList<WebSocketSession>();
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        users.add(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        users.remove(session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
    }

    public void sendMessgaeToUsers(TextMessage message) {
        for(WebSocketSession session:users) {
            if(session.isOpen()) {
                try {
                    session.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

(2)创建Interceptor拦截器web

@Component
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketHandshakeInterceptor.class);

    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {

    }
}

(3)进行配置spring

@Configuration
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketConfig.class);

    @Resource
    private WebSocketHandler webSocketHandler;

    @Resource
    private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(webSocketHandler,"/webSocketHandler.ws")
                .addInterceptors(webSocketHandshakeInterceptor);
        webSocketHandlerRegistry.addHandler(webSocketHandler,"/sockjs/webSocketHandler.ws")
                .addInterceptors(webSocketHandshakeInterceptor).withSockJS();
    }

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192*4);
        container.setMaxBinaryMessageBufferSize(8192*4);
        return container;
    }
}

** 我这里的路径/webSocketHandler.ws是以.ws结尾的。spring-mvc

(4)前端进行WebSocket链接websocket

<script src="sockjs.js"></script>
<script type="text/javascript">
    var websocket;
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:9999/webSocketHandler.ws");
    } else if ('MozWebSocket' in window) {
        websocket = new MozWebSocket("ws://localhost:9999/webSocketHandler.ws");
    } else {
        websocket = new SockJS("http://localhost:9999/sockjs/webSocketHandler.ws");
    }
    websocket.onopen = function (evnt) {
        console.log("open");
    };
    websocket.onmessage = function (evnt) {
        console.log(evnt);
    };
    websocket.onerror = function (evnt) {
        console.log("error");
    };
    websocket.onclose = function (evnt) {
        console.log("close");
    }
</script>

(5)以上四个步骤在网上均可以找到不少,我也是代码搬运工。完成以上四个步骤,运行出现:session

404

出现这个错误的缘由是:JEECG在web.xml对路径作了处理,以下:mvc

<servlet>
        <description>spring mvc servlet</description>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <description>spring mvc 配置文件</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

这里的路径只对后缀是.do和前缀是rest的作了转发,因此在这里须要添加一个servlet-mapping对后缀是.ws的作转发:app

<servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>*.ws</url-pattern>
    </servlet-mapping>

(6)再运行出现:

图片描述

后台出现以下问题:

javax.servlet.ServletException: No adapter for handler [org.springframework.web.socket.server.support.WebSocketHttpRequestHandler@44ae9ca8]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
    at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1141)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:917)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)

须要在spring-mvx.xml添加如下标签:

<mvc:annotation-driven/>

(7)接着运行,后台出现如下问题:

java.lang.ClassCastException: org.springframework.web.socket.server.support.WebSocketHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod

JEECG定义了一个AuthInterceptor对路径进行登陆权限拦截:

图片描述

AuthInterceptor类的preHandle方法默认是对请求类的方法进行处理,而我这里定义的.ws后缀是不符合这里的格式的,在spring-mvc.xml对AuthInterceptor的拦截路径进行处理:

图片描述

添加<mvc:exclude-mapping path="/*.ws"/>,对WebSocket的请求路径不作拦截。

(8)运行,已经成功链接了。

open

(9)创建一个测试类,进行后台消息推送:

@Controller
@RequestMapping("/webSocketController")
public class WebSocketController {
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private WebSocketHandler webSocketHandler;

    @RequestMapping(params = "sendMessage")
    @ResponseBody
    public void sendMessage(String message) {
        message = "Hello,world";
        TextMessage textMessage = new TextMessage(message);
        webSocketHandler.sendMessgaeToUsers(textMessage);
    }
}

访问http://localhost:9999/webSocketController.do?sendMessage,以下:

sendMessageToUsers

运行结果:

onmessage

以上就是本身在折腾JEECG整合WebSocket的一些心路历程。

相关文章
相关标签/搜索