spring-websocket下的前后端分离

目前的项目是前后端分离的,想在项目里增加对websocket的支持,这件事想做很久了,因为各种原因,一直脱到今天才做.大部分的都还是spring-websocket的,网上例子也很多,需要注意的主要有以下的内容

依赖

除了spring一些基础的jar包,还需要引入以下两个

      <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-websocketartifactId>
      <version>${spring.version}version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-messagingartifactId>
      <version>${spring.version}version>
    dependency>

dispatcher-servlet.xml

首先要在web.xml里配置dos

  <servlet>
    <servlet-name>dispatcherservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>/WEB-INF/dispatcher-servlet.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
    <async-supported>trueasync-supported>
  servlet>
  <servlet-mapping>
    <servlet-name>dispatcherservlet-name>
    <url-pattern>/url-pattern>  
  servlet-mapping>
  

然后在dispatcher-servlet.xml里配置转发规则


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <context:component-scan base-package="com.xxx.ws.controller" />
    <mvc:annotation-driven />
    <mvc:resources mapping="/js/**" location="view/js/"/>
   

    
    <websocket:message-broker application-destination-prefix="/app">
        <websocket:stomp-endpoint path="/wsConnect" >
            <websocket:sockjs/>
        websocket:stomp-endpoint>
        <websocket:simple-broker prefix="/topic,/queue"/>
    websocket:message-broker>


    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="rss" value="application/rss+xml" />
            map>
        property>
        <property name="defaultContentType" value="text/html"/>
    bean>
    
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <property name="viewResolvers">
            <list>
                <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
                <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

                    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
                    <property name="prefix" value="view/jsp/"/>
                    <property name="suffix" value=".jsp"/>
                bean>

            list>
        property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
                
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <constructor-arg>
                        <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
                    constructor-arg>
                bean>
            list>
        property>
    bean>
    

beans>

controller

@Controller
public class GreetingController
{
    private static Logger logger = LoggerFactory.getLogger(GreetingController.class);
    @MessageMapping("/wsConnect")//访问wsConnect建立ws连接
    @SendTo("/topic/qqq")//订阅/topic/qqq,后,返回信息会往对应的前端推送
    public Result addNum(CalcInput input) throws Exception {
       logger.debug(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));
        Thread.sleep(2000);
        Result result = new Result(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));

        return result;
    }
}

前端页面


<html>
<head>
    <title>Calculator App Using Spring 4 WebSockettitle>
    <script src="/js/sockjs-0.3.4.js">script>
    <script src="/js/stomp.js">script>
    <script type="text/javascript">

        var stompClient = null;

        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('calculationDiv').style.visibility = connected ? 'visible' : 'hidden';
            document.getElementById('calResponse').innerHTML = '';
        }

        function connect() {
            var socket = new SockJS('/websocket/wsConnect');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/qqq', function(calResult){
                    console.log("22222222222");
                    showResult(JSON.parse(calResult.body).result);
                });
            });

        }

        function disconnect() {
            stompClient.disconnect();
            setConnected(false);
            console.log("Disconnected");
        }

        function sendNum() {
            var num1 = document.getElementById('num1').value;
            var num2 = document.getElementById('num2').value;
            stompClient.send("/app/wsConnect", {}, JSON.stringify({ 'num1': num1, 'num2': num2 }));
        }

        function showResult(message) {
            var response = document.getElementById('calResponse');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }
    script>
head>
<body>
<noscript><h2>Enable Java script and reload this page to run Websocket Demoh2>noscript>
<h1>Calculator App Using Spring 4 WebSocketh1>
<div>
    <div>
        <button id="connect" onclick="connect();">Connectbutton>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnectbutton><br/><br/>
    div>
    <div id="calculationDiv">
        <label>Number One:label><input type="text" id="num1" /><br/>
        <label>Number Two:label><input type="text" id="num2" /><br/><br/>
        <button id="sendNum" onclick="sendNum();">Send to Addbutton>
        <p id="calResponse">p>
    div>
div>
body>
html>

apache配置

apache2.2的版本不支持ws,要使用2.4的版本.安装apache2.4
要支持ws协议,首先要把httpd.conf的LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so注释去掉,启用该模块

然后再配置ws的转发路径

  ProxyPass  /websocket/wsConnect/info    http://localhost:8080/websocket/wsConnect/info 
   ProxyPass  /websocket/  ws://localhost:8080/websocket/

启动程序,然后这个spring-websocket的例子就能跑起来了.
spring-websocket下的前后端分离_第1张图片

你可能感兴趣的:(spring-websocket下的前后端分离)