WebSocket(一):springboot集成webSocket

本文详细介绍了如何在Spring Boot项目中实现WebSocket功能,包括引入依赖、配置ServerEndpointExporter、创建WebSocketHandler、编写HTML页面和Controller,以及测试WebSocket的连接、发送和接收消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.引入pom文件

<!--web socket-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
   <groupId>javax</groupId>
   <artifactId>javaee-api</artifactId>
   <version>7.0</version>
   <scope>provided</scope>
</dependency>
<!--springBoot thymeleaf模板-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
   <version>1.5.1.RELEASE</version>
</dependency>

2.集成WebSocket

/**
 * @author tracyclock
 * @date 2018/10/18
 * 首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。
 * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
 */
@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

@Slf4j
@ServerEndpoint(value = "/webSocket" )
@Component
public class TracyWebSocket {

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法
     * 1.可通过@ServerEndpoint(value = "/webSocket/{key}" ) @PathParam("key") 传入必传值
     * 2.webSocket = new WebSocket("ws://localhost:9999/webSocket?key"); session.getQueryString() = key
     * key可以传入当期用户的唯一标识
     */
    @OnOpen
    public void onOpen(Session session) throws Exception{
        log.info("onOpen() queryString:{}",session.getQueryString());
        this.session = session;
        WebSocketMapUtil.put(session.getQueryString(),this);
        try {
            sendMessage("true" );
        } catch (IOException e) {
            log.info("onOpen() error:{}",e);
        }
    }

    /**
     * 连接关闭调用的方法
     * @throws Exception
     */
    @OnClose
    public void onClose() throws Exception{
        log.info("onClose()!!!");
        WebSocketMapUtil.remove(session.getQueryString());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        log.info("onMessage!!!!!");
        /*try {
            TracyWebSocket myWebSocket= ((TracyWebSocket) WebSocketMapUtil.get(session.getQueryString().replace("service", "client")));
            if(myWebSocket != null){
                myWebSocket.sendMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        System.out.println("来自客户端的消息:" + message);

        //群发消息
        /*for (TracyWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }*/
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error){
        log.info("onError() error:{}",error);
    }


    /**
     * 发送消息方法
     */
    public void sendMessage(String message) throws IOException {
        log.info("sendMessage() message:{}",message);
        //this.session.getAsyncRemote().sendText(message);
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.info("sendMessage() error:{}",e);
        }
    }

    /**
     * 群发消息方法
     */
    public void sendInfoAll(String message) throws IOException{
        log.info("sendInfoAll() start!");
        for(TracyWebSocket tracyWebSocket : WebSocketMapUtil.getValues()){
            tracyWebSocket.sendMessage(message);
        }
    }

    /**
     * 点对点,给客户端单发消息
     */
    public void sendInfoSingle(WsMessage wsMessage) throws IOException {
        log.info("sendInfoSingle() key:{} message:{}",wsMessage.getId(),wsMessage.getMessage());
        if(StringUtils.isNotBlank(wsMessage.getId())){
            TracyWebSocket tracyWebSocket = WebSocketMapUtil.get(wsMessage.getId());
            if(tracyWebSocket != null){
                try {
                    tracyWebSocket.sendMessage(wsMessage.getMessage().toString());
                } catch (IOException e) {
                    log.info("sendInfoSingle() error:{}",wsMessage.getId(),wsMessage.getMessage());
                }
            }
        }
    }

    /**
     * 对符合条件的客户端发送消息
     */
    public void sendInfoSet(Set<String> keySet, String message) throws IOException {
        log.info("sendInfoSet() key:{} message:{}",keySet,message);
        if(!CollectionUtils.isEmpty(keySet)){
            keySet.forEach(key -> {
                TracyWebSocket tracyWebSocket = WebSocketMapUtil.get(key);
                if(tracyWebSocket != null){
                    try {
                        tracyWebSocket.sendMessage(message);
                    } catch (IOException e) {
                        log.info("sendInfoSet() error:{}",e);
                    }
                }
            });
        }
    }
}
/**
 * @author tracyclock
 * 2018/09/04
 * 记录链接成功的用户
 */
public class WebSocketMapUtil {

    public static ConcurrentMap<String, TracyWebSocket> webSocketMap = new ConcurrentHashMap<>();

    public static void put(String key, TracyWebSocket tracyWebSocket){
        webSocketMap.put(key, tracyWebSocket);
    }

    public static TracyWebSocket get(String key){
        return webSocketMap.get(key);
    }

    public static void remove(String key){
        webSocketMap.remove(key);
    }

    public static Collection<TracyWebSocket> getValues(){
        return webSocketMap.values();
    }
}
/**
 * @author tracyclock
 * @date 2018/10/18
 * 自定义消息体
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WsMessage<T> implements Serializable{

    private static final long serialVersionUID = -3477023334141401126L;

    private T message;

    private String id;

}

3.编写html

webScoketA:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
Welcome<br/>
<input id="text" type="text" /><button onclick="send()">Send</button>    <button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        websocket = new WebSocket("ws://127.0.0.1:5678/webSocket?a");
    }
    else{
        alert('Not support webSocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("webSocket open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("webSocket close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += "---------------"+innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        $.ajax({
            type: "POST",
            dataType: 'json',
            contentType: 'application/json;charset=utf-8',
            url: "http://127.0.0.1:5678/webSocket/send",
            data: JSON.stringify({
                "message": message.toString(),
                "id": "b"
            }),
            success: function (data){

            }
        })
        //websocket.send(message);
        document.getElementById('message').innerHTML += message + "-------------" + '<br/>';
    }
</script>
</html>

webScoketB:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
Welcome<br/>
<input id="text" type="text" /><button onclick="send()">Send</button>    <button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        websocket = new WebSocket("ws://127.0.0.1:5678/webSocket?b");
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += "---------------"+innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        $.ajax({
            type: "POST",
            dataType: 'json',
            contentType: 'application/json;charset=utf-8',
            url: "http://127.0.0.1:5678/webSocket/send",
            data: JSON.stringify({
                "message": message.toString(),
                "id": "a"
            }),
            success: function (data){

            }
        })
        //websocket.send(message);
        document.getElementById('message').innerHTML += message + "-------------" + '<br/>';
    }
</script>
</html>

4.编写controller

@Slf4j
@Controller
@RequestMapping("/webSocket")
public class WebSocketController {

    @Autowired
    private TracyWebSocket tracyWebSocket;

    @RequestMapping(value = "/send",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public void send(@RequestBody WsMessage wsMessage) {
        log.info("send!!!!!!!!!!!!!!");
        try {
            tracyWebSocket.sendInfoSingle(wsMessage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/test")
    public void test() {
        log.info("test!!!!!!!!!!!!!!");
    }

    @RequestMapping("/webSocketA")
    public String webSocketA() {
        log.info("go webSocketA");
        return "webSocketA";
    }

    @RequestMapping("/webSocketB")
    public String webSocketB() {
        log.info("go webSocketB");
        return "webSocketB";
    }
}

5.结果展示

 

6.简单的webSocket就成功了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值