天天看點

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

使用websocket需要考慮的浏覽器的支援(ie<10不支援),目前主流的浏覽器都能很好的支援websocket。

websocket協定中有一些子協定,可以從更高的層次實作程式設計模型,就像我們使用http而不是tcp一樣。這些子協定有stomp,wamp等。

本教程隻考慮websocket的簡單實用,包含spring對jsr-356的支援及spring websocket api。

通過spring初始化一個endpoint,隻需配置一個springconfigurator在類上的@serverendpoint注解上。

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import javax.websocket.server.serverendpoint;  

import org.springframework.web.socket.server.endpoint.springconfigurator;  

@serverendpoint(value = "/echo", configurator = springconfigurator.class);  

public class echoendpoint {  

  private final echoservice echoservice;  

  @autowired  

  public echoendpoint(echoservice echoservice) {  

    this.echoservice = echoservice;  

  }  

  @onmessage  

  public void handlemessage(session session, string message) {  

    // ...  

}  

 上例假設springcontextloaderlistener用來加載配置,這是個典型的web應用。servlet容器将通過掃描@serverendpoint和springconfigurator初始化一個新的websocket會話。

如果你想使用一個單獨的執行個體而不使用servlet容器掃描,将echoendpoint類聲明稱一個bean,并增加一個serverendpointexporter的bean:

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import org.springframework.web.socket.server.endpoint.serverendpointexporter;  

@configuration  

public class endpointconfig {  

  @bean  

  public echoendpoint echoendpoint() {  

    return new echoendpoint(echoservice());  

  public echoservice echoservice() {  

  public serverendpointexporter endpointexporter() {  

    return new serverendpointexporter();  

 echoendpoint 可以通過endpointregistration釋出:

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import org.springframework.web.socket.server.endpoint.serverendpointregistration;  

  public endpointregistration echoendpoint() {  

    return new endpointregistration("/echo", echoendpoint.class);  

  // ..  

spring websocket api提供了sockjs的支援,且有些容器如jetty 9目前還沒有對jsr-356的支援,是以有spring websocket api是必要的。

spring websocket api的核心接口是websockethandler。下面是一個處理文本消息的handler的實作:

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import org.springframework.web.socket.adapter.textwebsockethandleradapter;  

public class echohandler extends textwebsockethandleradapter {  

  @override  

  public void handletextmessage(websocketsession session, textmessage message) throws exception {  

    session.sendmessage(message);  

websockethandler可以通過websockethttprequesthandler插入到spring mvc裡:

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import org.springframework.web.socket.server.support.websockethttprequesthandler;  

public class webconfig {  

  public simpleurlhandlermapping handlermapping() {  

    map<string, object> urlmap = new hashmap<string, object>();  

    urlmap.put("/echo", new websockethttprequesthandler(new echohandler()));  

    simpleurlhandlermapping hm = new simpleurlhandlermapping();  

    hm.seturlmap(urlmap);  

    return hm;  

sockjs是一個腳本架構,它提供類似于websocket的程式設計模式但是可以适應不同的浏覽器(包括不支援websocket的浏覽器)。

開啟sockjs的支援,聲明一個sockjsservice,和一個url映射,然後提供一個websockethandler來處理消息。雖然我們是喲個sockjs我們開發的方式是一樣的,但是随着浏覽器的不同傳輸的協定可以是http streaming,long polling等。

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

import org.springframework.web.socket.sockjs.sockjsservice;  

// ...  

    sockjsservice sockjsservice = new defaultsockjsservice(taskscheduler());  

    urlmap.put("/echo/**", new sockjshttprequesthandler(sockjsservice, new echohandler()));  

  public threadpooltaskscheduler taskscheduler() {  

    threadpooltaskscheduler taskscheduler = new threadpooltaskscheduler();  

    taskscheduler.setthreadnameprefix("sockjs-");  

    return taskscheduler;  

在我們實際使用中我們會使用websocketconfigurer集中注冊websocket服務:

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

@enablewebmvc  

@enablewebsocket//開啟websocket  

public class webconfig extends webmvcconfigureradapter implements websocketconfigurer {  

    @override  

    public void registerwebsockethandlers(websockethandlerregistry registry) {  

        registry.addhandler(echowebsockethandler(), "/echo"); //提供符合w3c标準的websocket資料  

        registry.addhandler(snakewebsockethandler(), "/snake");  

        registry.addhandler(echowebsockethandler(), "/sockjs/echo").withsockjs();//提供符合sockjs的資料  

        registry.addhandler(snakewebsockethandler(), "/sockjs/snake").withsockjs();  

    }  

    @bean  

    public websockethandler echowebsockethandler() {  

        return new echowebsockethandler(echoservice());  

    public websockethandler snakewebsockethandler() {  

        return new perconnectionwebsockethandler(snakewebsockethandler.class);  

    public defaultechoservice echoservice() {  

        return new defaultechoservice("did you say \"%s\"?");  

    // allow serving html files through the default servlet  

    public void configuredefaultservlethandling(defaultservlethandlerconfigurer configurer) {  

        configurer.enable();  

Spring4.0系列9-websocket簡單應用1、Java API for WebSocket(JSR-356)2、Spring WebSocket API

ws = new sockjs(url, undefined, {protocols_whitelist: transports}) ;   //初始化 websocket  

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(event);  

 ws.send(message);//向服務端發送消息