SpringMVC+WebSocket整合

来源:互联网 发布:js中srcelement是什么 编辑:程序博客网 时间:2024/06/05 00:12
最近项目有需求要实现全双工(android端实时更新数据),那果断采用websocket,之前对websocket没啥研究。现在spring也支持了websocket,故写此demo,经过半天的调试和查询资料,终于能通信了。

pom.xml

添加springmvc,websocket所依赖的jar包
<dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-core</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-web</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-context-support</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-webmvc</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-test</artifactId>    <version>${spring.version}</version>    <scope>test</scope></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-jdbc</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-test</artifactId>    <version>4.1.1.RELEASE</version></dependency><!--JSTL--><dependency>    <groupId>javax.servlet</groupId>    <artifactId>servlet-api</artifactId>    <version>2.5</version></dependency><dependency>    <groupId>javax.servlet</groupId>    <artifactId>jstl</artifactId>    <version>1.2</version></dependency><dependency>    <groupId>javax.servlet.jsp</groupId>    <artifactId>jsp-api</artifactId>    <version>2.1</version>    <scope>provided</scope></dependency><dependency>    <groupId>jstl</groupId>    <artifactId>jstl</artifactId>    <version>${jstl}</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.3.0</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.3.0</version></dependency><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>

创建和配置一个websockethandler

创建一个websocket服务,可以implementing WebSocketHandler,也可以extends TextWebSocketHandler or BinaryWebSocketHandler,如下:

public class AnalysisWebSocketHandler extends TextWebSocketHandler{    @Override    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {    //TODO something    }}
@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {    @Override    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {        registry.addHandler(myHandler(), "/myHandler");    }    @Bean    public WebSocketHandler myHandler() {        return new MyHandler();    }}

然后在spring-servlet.xml中配置

<bean id="myHandler" class="com.gogbuy.analysis.system.websocket.AnalysisWebSocketHandler"/><websocket:handlers>    <websocket:mapping path="/myHandler" handler="myHandler"/>      <websocket:handshake-interceptors>          <bean class="com.gogbuy.analysis.system.websocket.HandshakeInterceptor"/>      </websocket:handshake-interceptors></websocket:handlers>

当然握手的handshake可以直接使用spring 的HttpSessionHandshakeInterceptor,也可以继承它,我这里就继承了HttpSessionHandshakeInterceptor。

到这里配置基本就OK了。

前端

前端主要是借鉴了这里,做了一些小修改。

<!DOCTYPE html><html><head>    <title>WebSocket demo</title>    <meta name="viewport"          content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>    <style type="text/css">        #connect-container {            width: 100%;        }        #connect-container div {            padding: 5px;        }        #console-container {            width: 100%;        }        #console {            border: 1px solid #CCCCCC;            border-right-color: #999999;            border-bottom-color: #999999;            height: 170px;            overflow-y: scroll;            padding: 5px;            width: 100%;        }        #console p {            padding: 0;            margin: 0;        }    </style>    <script src="http://cdn.jsdelivr.net/sockjs/1/sockjs.min.js"></script>    <script type="text/javascript">        var ws = null;        var url = null;        var transports = [];        function setConnected(connected) {            document.getElementById('connect').disabled = connected;            document.getElementById('disconnect').disabled = !connected;            document.getElementById('echo').disabled = !connected;        }        function connect() {            alert("url:" + url);            if (!url) {                alert('Select whether to use W3C WebSocket or SockJS');                return;            }            if ('WebSocket' in window) {                ws = new WebSocket(url);//ws://localhost:8080/myHandler            } else if ('MozWebSocket' in window) {                ws = new MozWebSocket(url);            } else {                ws = new SockJS(url);            }            ws.onopen = function () {                setConnected(true);                log('Info: connection opened.');            };            ws.onmessage = function (event) {                log('Received: ' + event.data);            };            ws.onclose = function (event) {                setConnected(false);                log('Info: connection closed.');                log(JSON.stringify(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) {            alert(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 Javascript! Websockets    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('/myHandler');">        <label for="radio1">W3C WebSocket</label>        <br>        <input id="radio2" type="radio" name="group1" onclick="updateUrl('/myHandler');">        <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="width: 350px">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>

效果如下:
image

结束

到这里,配置就OK啦,更多高级的功能,大家自己发挥了,在发挥聪明才智之前,我们需要能够跑起来,对不对。
demo地址:GitHub
另外,spring的官网文档很全,
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#websocket

1 0