欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring WebSocket示例详解

程序员文章站 2024-03-08 14:32:22
场景 websocket是html5新增加特性之一,目的是浏览器与服务端建立全双工的通信方式,解决http请求-响应带来过多的资源消耗,同时对特殊场景应用提供了全新的实现...

场景

websocket是html5新增加特性之一,目的是浏览器与服务端建立全双工的通信方式,解决http请求-响应带来过多的资源消耗,同时对特殊场景应用提供了全新的实现方式,比如聊天、股票交易、游戏等对对实时性要求较高的行业领域。

背景

在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,html5定义了websocket协议,能更好的节省服务器资源和带宽并达到实时通讯。目前各大主流浏览器都支持websocket,ie浏览器要ie10+

一、pom依赖

pom依赖,spring4.1.4.release,spring核心依赖请自行添加,下面是websocket相关jar

<dependency>
  <groupid>javax.websocket</groupid>
  <artifactid>javax.websocket-api</artifactid>
  <version>1.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupid>org.springframework</groupid>
  <artifactid>spring-websocket</artifactid>
  <version>4.1.4.release</version>
</dependency>

二、websocket入口

@configuration
@enablewebmvc
@enablewebsocket
public class websocketconfig extends webmvcconfigureradapter implements websocketconfigurer {
  @override
  public void registerwebsockethandlers(websockethandlerregistry registry) {
    //允许连接的域,只能以http或https开头
    string[] allowsorigins = {"http://www.xxx.com"};
    
    //webim websocket通道
    registry.addhandler(chatwebsockethandler(),"/      websocketimserver").setallowedorigins(allowsorigins).addinterceptors(myinterceptor());
    registry.addhandler(chatwebsockethandler(), "/sockjs/w     ebsocketimserver").setallowedorigins(allowsorigins).addinterceptors(myinterceptor()).withsockjs();
  }
  @bean
  public chatwebsockethandler chatwebsockethandler() {
    return new chatwebsockethandler();
  }
  @bean
  public websockethandshakeinterceptor myinterceptor(){
    return new websockethandshakeinterceptor();
  }
}

1.实现websocketconfigurer接口,重写registerwebsockethandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册handler、sockjs支持和拦截器。

2.registry.addhandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。

3.setallowedorigins(string[] domains),允许指定的域名或ip(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用"*"号,如果指定了域名,则必须要以http或https开头。

4.addinterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。

5.spring websocket也支持stomp协议,下回再分享。

三、拦截器实现

public class websockethandshakeinterceptor implements handshakeinterceptor {

  @override
  public boolean beforehandshake(serverhttprequest request, serverhttpresponse response, websockethandler wshandler, map<string, object
        > attributes) throws exception {
    if (request instanceof servletserverhttprequest) {
      attributes.put("username",username);
    }
    return true;
  }

  @override
  public void afterhandshake(serverhttprequest request, serverhttpresponse response, websockethandler wshandler, exception exception) {

  }
}

beforehandshake,在调用handler前处理方法。常用在注册用户信息,绑定websocketsession,在handler里根据用户信息获取websocketsession发送消息。

四、handler处理类

public class chatwebsockethandler extends textwebsockethandler{
  
  private final static list<websocketsession> sessions = collections.synchronizedlist(new arraylist<websocketsession>());
  //接收文本消息,并发送出去
  @override
  protected void handletextmessage(websocketsession session, textmessage message) throws exception {
    chattextmessagehandler(message.getpayload());
    super.handletextmessage(session, message);
  }
  //连接建立后处理
  @suppresswarnings("unchecked")
  @override
  public void afterconnectionestablished(websocketsession session) throws exception {
    logger.debug("connect to the websocket chat success......");
    sessions.add(session);
    //处理离线消息
  }
  //抛出异常时处理
  @override
  public void handletransporterror(websocketsession session, throwable exception) throws exception {
    if(session.isopen()){
      session.close();
    }
    logger.debug("websocket chat connection closed......");
    sessions.remove(session);
  }
  //连接关闭后处理
  @override
  public void afterconnectionclosed(websocketsession session, closestatus closestatus) throws exception {
    logger.debug("websocket chat connection closed......");
    sessions.remove(session);
  }

  @override
  public boolean supportspartialmessages() {
    return false;
  }
}

五、客户端连接

var host = window.location.host;
var websocket;
if ('websocket' in window) {
  websocket = new reconnectingwebsocket("ws://"
    + host + "/websocketimserver", null, {debug:true, maxreconnectattempts:4});
} else if ('mozwebsocket' in window) {
  websocket = new mozwebsocket("ws://" + host
    + "/websocketimserver");
} else {
  websocket = new sockjs("http://" + host
      + "/sockjs/websocketimserver");
}
websocket.onopen = function(evnt) {
  console.log("websocket连接上");
};
websocket.onmessage = function(evnt) {
  messagehandler(evnt.data);
};
websocket.onerror = function(evnt) {
  console.log("websocket错误");
};
websocket.onclose = function(evnt) {
  console.log("websocket关闭");
}

这里用到了reconnectingwebsocket.js,对浏览器自带websocket添加了扩展,例如重连,连接超时时间,失败重连间隔,尝试连接最大次数等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。