SpringMVC整合WebSocket

这块功能早就想实现了,但一直忙于其他项目的功能,直到昨天才正式开始研究。

Spring4已经加入了对Websocket支持。
1. 引入Spring4的jar包,以及Spring websocket的jar包,如下图
Image
2. web.xml文件用3.0版本。
< web-app
      xmlns:xsi= “http://www.w3.org/2001/XMLSchema-instance”
      xmlns= “http://java.sun.com/xml/ns/javaee”
      xmlns:web= “http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”
      xsi:schemaLocation= “http://java.sun.com/xml/ns/javaee
                     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”
      version= “3.0” >
 
3. Tomcat用7或以上,JDK用7或以上,其他Spring配置文件按默认即可,这里用的是注解方式。
4. 后台代码如下:
WebSocketConfig.java
package com.noter.websocket.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
 
import com.noter.websocket.handler.SystemWebSocketHandler;
 
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
           WebSocketConfigurer {
 
      @Override
      public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
           registry.addHandler(systemWebSocketHandler(), “/webSocketServer.do” );
     }
 
      @Bean
      public WebSocketHandler systemWebSocketHandler() {
            return new SystemWebSocketHandler();
     }
 
}
 
SystemWebSocketHandler.java
package com.noter.websocket.handler;
 
import java.io.IOException;
import java.util.ArrayList;
 
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
 
public class SystemWebSocketHandler implements WebSocketHandler {
     
 
    private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();;
 
 
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
     System. out.println( “ConnectionEstablished” );
        users.add(session);
    }
 
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
     System. out.println( “session id:” + session.getId());
     sendMessageToUsers(session.getId(),(TextMessage) message);
    }
 
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){
            session.close();
        }
        users.remove(session);
    }
 
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        users.remove(session);
    }
 
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
 
    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public void sendMessageToUsers(String excep, TextMessage message) {
        for (WebSocketSession user : users) {
            try {
                if (user.isOpen()&& !user.getId().equals(excep)) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
}
5. 前台jsp代码:
<%@ page language = “java” contentType= “text/html; charset=UTF-8”
      pageEncoding= “UTF-8” %>
<%
     String path = request.getContextPath();
     String basePath = request.getScheme() + “://”
     + request.getServerName() + “:” + request.getServerPort()
     + path + “/”;
%>
<! DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” >
< html>
< head>
< meta http-equiv= “Content-Type” content = “text/html; charset=UTF-8”>
< title> WebSocket/SockJS Echo Sample (Adapted from Tomcat’s echo sample)</ title>
    <style type = “text/css”>
        #connect-container {
            floatleft;
            width400px
        }
 
        #connect-container div {
            padding5px;
        }
 
        #console-container {
            floatleft;
            margin-left15px;
            width400px;
        }
 
        #console {
            border1px solid #CCCCCC ;
            border-right-color#999999;
            border-bottom-color#999999;
            height170px;
            overflow-yscroll;
            padding5px;
            width100%;
        }
 
        #console p {
            padding0;
            margin0;
        }
    </style >
 
    <script src = “../assets/js/sockjs-0.3.min.js”></ script >
 
    <script type = “text/javascript”>
        var ws = null;
        var url = null;
        var transports = [];
       
        var basePath =  <%= basePath%> “;
        var wsPath = basePath.replace( “http://”, “ws://” );
 
        function setConnected(connected) {
            document.getElementById( ‘connect’ ).disabled = connected;
            document.getElementById( ‘disconnect’ ).disabled = !connected;
            document.getElementById( ‘echo’ ).disabled = !connected;
        }
 
        function connect() {
            if (!url) {
                alert( ‘Select whether to use W3C WebSocket or SockJS’);
                return ;
            }
           
                
            ws = new WebSocket(wsPath+‘webSocketServer.do’ ); /* (url.indexOf(‘sockjs’) != -1) ?
                new SockJS(url, undefined, {protocols_whitelist: transports}) :  */
               
               
            ws.onopen = function () {
                setConnected( true );
                log( ‘Info: connection opened.’ );
            };
           
            ws.onmessage = function (event) {
                 for ( var in event.originalTarget){
                     console.log( “event[“ +i+“]:” +event.originalTarget[i]);
                }
                log( ‘Received: ‘ + event.data);
            };
           
            ws.onclose = function (event) {
                setConnected( false );
                log( ‘Info: connection closed.’ );
                log(event);
            };
        }
 
        function disconnect() {
            if (ws != null) {
                ws.close();
                ws = null ;
            }
            setConnected( false );
        }
 
        function echo() {
            if (ws != null) {
                var message = document.getElementById(‘message’ ).value;
                log( ‘Sent: ‘ + message);
                ws.send(message);
            } else {
                alert( ‘connection not established, please connect.’);
            }
        }
 
        function updateUrl(urlPath) {
            if (urlPath.indexOf(‘sockjs’ ) != -1) {
                url = urlPath;
                document.getElementById(‘sockJsTransportSelect’ ).style.visibility = ‘visible’;
            }
            else {
              if (window.location.protocol == ‘http:’) {
                  url = ‘ws://’ + window.location.host + urlPath;
              } else {
                  url = ‘wss://’ + window.location.host + urlPath;
              }
              document.getElementById(‘sockJsTransportSelect’ ).style.visibility = ‘hidden’;
            }
        }
 
        function updateTransport(transport) {
          transports = (transport == ‘all’ ) ?  [] : [transport];
        }
       
        function log(message) {
            var console = document.getElementById( ‘console’);
            var p = document.createElement( ‘p’);
            p.style.wordWrap = ‘break-word’ ;
            p.appendChild(document.createTextNode(message));
            console.appendChild(p);
            while (console.childNodes.length > 25) {
                console.removeChild(console.firstChild);
            }
            console.scrollTop = console.scrollHeight;
        }
    </script >
</ head>
< body>
< noscript>< h2 style=” color#ff0000 >Seems your browser doesn’t support JavascriptWebsockets
    rely on Javascript being enabled. Please enable
    Javascript and reload this page!</ h2></ noscript >
< div>
    <div id = “connect-container”>
        <input id = “radio1” type= “radio” name= “group1” onclick =“updateUrl(‘ ${contextPath} /webSocketServer’);”>
            <label for = “radio1”> W3C WebSocket</ label >
        <br >
        <input id = “radio2” type= “radio” name= “group1” onclick =“updateUrl(‘/spring-websocket-test/sockjs/echo’);” >
            <label for = “radio2”> SockJS</ label >
        <div id = “sockJsTransportSelect” style=” visibility: hidden;” >
            <span >SockJS transport: </ span>
            <select onchange =“updateTransport(this.value)” >
              <option value = “all”> all</ option >
              <option value = “websocket”> websocket</ option >
              <option value = “xhr-polling”> xhr-polling </option >
              <option value= “jsonp-polling” >jsonp-polling </ option>
              <option value= “xhr-streaming” >xhr-streaming </ option>
              <option value= “iframe-eventsource” >iframe– eventsource</ option >
              <option value= “iframe-htmlfile” >iframe– htmlfile</ option >
            </ select>
        </div >
        <div >
            <button id = “connect” onclick =“connect();” >Connect </ button>
            <button id = “disconnect” disabled= “disabled” onclick =“disconnect();” >Disconnect </ button>
        </div >
        <div >
            <textarea id = “message” style=” width350px >Here is a message!</ textarea>
        </div >
        <div >
            <button id = “echo” onclick= “echo();” disabled =“disabled” >Echo message </ button>
        </div >
    </div >
    <div id = “console-container”>
        <div id = “console”></ div>
    </div >
</ div>
</ body>
</ html>
 
注:最后只要注意你定义的springmvc拦截的路径规则和请求路径即可,我一开始总是报404错误,就是路径写错了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注