spring4使用websocket

ygfb 9年前

       看到spring4的介绍上说已经支持websocket了,尝试了一下之后各种坑,不如servlet简单,写篇文章来讲解一下自己遇到的坑。

       环境:tomcat8+spring4.1.6+jdk8+nginx1.8.0

       先是看了下网络上的人的实现,千奇百怪,干脆直接在spring的官方文档上观望了一下,看了下他们官方的实现,然而我用的是springmvc,总是失败,报的错误翻译过来大致是找不到请求,所有的页面请求都找不到,找到原因是WebSocketConfig在继承AbstractWebSocketMessageBrokerConfigurer的时候注解上需要加上对springMVC的支持,即@EnableWebMvc,和你在spring配置文件里配置包扫描一个用处。废话不多说,先上代码。

import org.springframework.context.annotation.Configuration;  import org.springframework.messaging.simp.config.MessageBrokerRegistry;  import org.springframework.web.servlet.config.annotation.EnableWebMvc;  import org.springframework.web.socket.config.annotation.*;     @Configuration  @EnableWebMvc  @EnableWebSocketMessageBroker  public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {         @Override      public void configureMessageBroker(MessageBrokerRegistry config) {          config.enableSimpleBroker("/tweet");          config.setApplicationDestinationPrefixes("/websocket");      }         public void registerStompEndpoints(StompEndpointRegistry registry) {          registry.addEndpoint("/hello").withSockJS();      }     }



      以上是websocket配置类,下面是请求。

import com.yuorfei.bean.ResultData;  import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory;  import org.springframework.messaging.handler.annotation.MessageMapping;  import org.springframework.messaging.handler.annotation.SendTo;  import org.springframework.stereotype.Controller;     @Controller("chat")  public class ChatAction {         private static final Log log = LogFactory.getLog(MessageAction.class);         @MessageMapping("/hello")      @SendTo("/tweet/fuck")      public ResultData chat(String message) throws Exception {          long time = System.currentTimeMillis();          log.info(time+":"+message);          return new ResultData(time,true,message);      }     }


      请求类准备好了之后写前端代码:

      前端代码需要引入的js有sockjs-1.0.3.min.js,stomp.min.js两个,去官网下最新的就行,我目前用的是最新的。

<!DOCTYPE html>  <html>  <head>      <meta charset="utf-8">      <meta http-equiv="X-UA-Compatible" content="IE=edge">      <script src="/dest/js/fun/chat/sockjs-1.0.3.min.js"></script>      <script src="/dest/js/fun/chat/stomp.min.js"></script>      <!-- 为了方便起见,js我就直接这么放这儿了 -->      <script>          var stompClient = null;                        function setConnected(connected) {              document.getElementById('connect').disabled = connected;              document.getElementById('disconnect').disabled = !connected;              document.getElementById('conversationDiv').style.visibility =                   connected ? 'visible' : 'hidden';              document.getElementById('response').innerHTML = '';          }                        function connect() {              var socket = new SockJS('/hello');              stompClient = Stomp.over(socket);              stompClient.connect({}, function(frame) {                  setConnected(true);                  console.log('Connected: ' + frame);                  stompClient.subscribe('/tweet/fuck', function(greeting){                      showGreeting(JSON.parse(greeting.body).code+" : "+                          JSON.parse(greeting.body).message);                  });              });          }                        function disconnect() {              if (stompClient != null) {                  stompClient.disconnect();              }              setConnected(false);              console.log("Disconnected");          }                        function sendMessage() {              var message = document.getElementById('message').value;              stompClient.send("/websocket/hello", {}, JSON.stringify({ 'message': message }));          }                function showGreeting(message) {              var response = document.getElementById('response');              var p = document.createElement('p');              p.style.wordWrap = 'break-word';              p.appendChild(document.createTextNode(message));              response.appendChild(p);          }      </script>  </head>  <body onload="disconnect()">      <noscript>          <h2 style="color: #ff0000">不支持的浏览器版本,丫的是不是用IE了,你这简直是摧残程序员的生命</h2>      </noscript>            <a href="${homeUrl!"/"}"><h5>返回与或非网站首页</h5></a>      <hr/>            <p>这只是一个SpringMVC的websocket例子</p>            <div>          <div>              <button id="connect" onclick="connect();">连接</button>              <button id="disconnect" disabled="disabled" onclick="disconnect();">              断开连接</button>          </div>          <div id="conversationDiv">              <label>你要说什么</label><input type="text" id="message" />              <button id="sendMessage" onclick="sendMessage();">发送</button>              <p id="response"></p>          </div>      </div>      <hr/>  </body>  </html>



       到了这里就ok了,但是运行却发现会报错,错误信息翻译过来大致意思是:没有引入jackson2的包 或者 socket消息转换没有配置。

       猛然一想我的确没有引入jackson2,赶紧maven把jackson2的依赖加进来,很久以前用过jackson,然而不知道2里头只引入core的jar包是不行的,还需要

jackson-databind和jackson-annotations,为了方便我索性全加入进来了(真是够大的,不如fastjson清爽)。


       这样就ok了,配置好了之后发送消息,正常接收,处理,ok,控制台不报烦人的错了。

       已经部署在线上了, 地址:websocket  

       小站,水管比较细,速度稍慢,嘿。