spring环境整合webscoket

一:webscoket简介

Webscoket是一个基于HTTP的持久化协议,服务端、客户端可以双向通信,不同于http,只能客户端请求服务端,服务端再返回,而WebScoket可以使服务端向客户端发起连接,客户端同样也可以像服务端发起请求。

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

二:集成spring环境

1)webscoket的jar:

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-messaging</artifactId>

<version>4.2.4.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-websocket</artifactId>

扫描二维码关注公众号,回复: 3806296 查看本文章

<version>4.2.4.RELEASE</version>

</dependency>

2)webscoket配置类,该类被spring容器加载(在spring扫描包的路径下)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
    @Bean
    public WebSocketHandler myHandler() {
        return new MyWebSocketHandler();
    }
//接收到ws://开头的请求会触发webscoket拦截器,例如:ws://localhost:9101//ws?uid=1
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/ws").addInterceptors(new HandShake());
        registry.addHandler(myHandler(), "/ws/sockjs").addInterceptors(new HandShake()).withSockJS();
    }
}

3)创建webscoket拦截器,在spring容器中也就是在spring扫描的包路径下

import java.util.Map;
import javax.servlet.http.HttpSession;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
/**
 * webscoke拦截器实现
 */
public class HandShake implements HandshakeInterceptor {
    //客户端建立与服务端连接时触发该拦截器,attributes可以在webscoket处理器中的    WebSocketSession获取到设置的参数信息
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        //true:放行,false:拦截
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception exception) {
    }
}

4)创建webscoket处理器,在spring扫描包的路径下。

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.github.dunwu.spring.websocket.entity.Message;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

@Component
public class MyWebSocketHandler implements WebSocketHandler {
    private static final Logger logger = LoggerFactory.getLogger(MyWebSocketHandler.class);

    /**
     * 建立连接后执行
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
      
    }

    /**
     * 消息处理,在客户端通过Websocket API发送的消息会经过这里,然后进行相应的处理
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {

    }

    /**
     * 消息传输错误处理
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
    }

    /**
     * 客户端关闭连接后触发
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
       
    }
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param message
     * @throws IOException
     */
    public void broadcast(final TextMessage message) throws IOException {
      
    }

    /**
     * 给某个用户发送消息
     *
     * @param userName
     * @param message
     * @throws IOException
     */
    private void sendMessageToUser(Long uid, TextMessage message) throws IOException {
session.sendMessage(message);
}

四:webscoket客户端配置

webscoket是基于H5的,所以可以直接new Websocket()创建对象

var websocket;
var path="localhost:8080";
//创建webscoket对象
if ('WebSocket' in window) {
   websocket = new WebSocket("ws://" + path + "/ws?uid="+uid);
} else if ('MozWebSocket' in window) {
   websocket = new MozWebSocket("ws://" + path + "/ws?uid="+uid);
} else {
   websocket = new SockJS("http://" + path + "/ws/sockjs?uid="+uid);
}
//webscoket与服务器建立连接后触发
websocket.onopen = function(event) {
   console.log("WebSocket:已连接");
   console.log(event);
};
//服务端调用webscoketSession.sendMessage()方法后,客户端触发此方法onmessage
websocket.onmessage = function(event) {
   var data=JSON.parse(event.data);
   console.log("WebSocket:收到一条消息",data);
};
//通信发生错误时触发
websocket.onerror = function(event) {
   console.log("WebSocket:发生错误 ");
   console.log(event);
};
//关闭连接时触发
websocket.onclose = function(event) {
   console.log("WebSocket:已关闭");
   console.log(event);
}
//客户端发送消息到服务端
var data={};//自定义发送json数据
data["from"]="xxx"
data["fromName"]="xxx"
data["to"]="xxx";
data["text"]="xxx";
websocket.send(JSON.stringify(data));
//关闭连接
websocket.close();

猜你喜欢

转载自blog.csdn.net/qq_15076569/article/details/83476239