spring WebSocket示例详解

网友投稿 212 2023-06-16


spring WebSocket示例详解

场景

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

javax.websocket

javax.websocket-api

1.0

provided

org.springframework

spring-websocket

4.1.4.RELEASE

二、WebSocket入口

@Configuration

@EnableWebMvc

@EnableWebSocket

public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

//允许连接的域,只能以http或https开头

String[] allowsOrigins = {"http://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

> 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 sessions = Collections.synchronizedList(new ArrayList());

//接收文本消息,并发送出去

@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添加了扩展,例如重连,连接超时时间,失败重连间隔,尝试连接最大次数等。

> 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 sessions = Collections.synchronizedList(new ArrayList());

//接收文本消息,并发送出去

@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添加了扩展,例如重连,连接超时时间,失败重连间隔,尝试连接最大次数等。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 程序员容易犯的10个SQL错误
下一篇:详解JAVA后端实现统一扫码支付:微信篇
相关文章

 发表评论

暂时没有评论,来抢沙发吧~