websocket简单使用--基于springboot+vue项目


一、websocket简单介绍

WebSocket是一种在单个TCP连接上进行全双工通信的协议。该协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范,同时WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在WebSocket中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。这种持久连接使得服务器可以主动向客户端推送数据,而不需要等待客户端的请求。这种特性使得WebSocket在实时通信、多人在线游戏、在线教育、音视频聊天等领域具有广泛的应用。

WebSocket的工作原理是在HTTP协议上建立一种全双工的通信方式,使得客户端和服务器之间可以建立一次连接,然后保持这个连接的开放状态,而不需要在每次通信后关闭连接。WebSocket通过HTTP/1.1协议的101状态码进行握手,并通过浏览器发出请求,之后服务器进行回应来建立连接。

二、websocket优缺点

WebSocket具有以下优点:

1.实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据,而不需要等待客户端的请求。
2.较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小,从而显著减少了开销。
3.更好的二进制支持:Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
4.保持连接状态:与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。

然而,WebSocket也存在一些缺点:

1.兼容性问题:WebSocket协议在一些旧版本的浏览器上不被支持,需要通过polyfill或者其他技术手段来解决兼容性问题。
2.服务器资源占用:由于WebSocket的长连接特性,服务器需要维护大量的连接,这可能会占用较多的服务器资源。
3.安全性问题:WebSocket连接需要特殊的安全设置,以防止恶意攻击和数据泄漏。

总的来说,WebSocket是一种强大的通信协议,适用于需要实时通信和双向数据传输的应用场景。在选择使用WebSocket时,需要根据具体的需求和场景来评估其优缺点。

三、简单使用

1.服务端

1.创建springboot项目,并导入常用依赖
2.导入websocket依赖

     <!--websocket依赖包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

3.创建一个websockt配置类

package com.etime.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @Description websocket 配置类
 * @Date 2024/5/20 10:28
 * @Author liukang
 **/
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverendpointExporter(){
        return new ServerEndpointExporter();
    }
}

4.创建websocket服务终端类

package com.etime.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description 监听websocket地址  /myWs
 * @Date 2024/5/18 20:10
 * @Author liukang
 **/
@ServerEndpoint("/myWs") // websocket终端地址
@Component // 将该类交给spring管理
@Slf4j // 用于输出日志信息
public class WsServerEndPoint {
    // ConcurrentHashMap 和hashMap的区别是 ConcurrentHashMap是线程安全的
    static Map<String,Session> sessionMap = new ConcurrentHashMap<>();
    /**
     *  websocket建立链接时触发方法
     * @author liukang
     * @date 20:15 2024/5/18
     * @param session 每一个websocket的链接 对于服务端都是一个session
     **/
    @OnOpen
    public void onOpen(Session session){
        // 建立连接时,将session存入map中
      sessionMap.put(session.getId(),session);
      log.info("websocket is open");
    }

    /**
     * 收到了客户端消息时触发方法
     * @author liukang
     * @date 20:20 2024/5/18
     * @param text 客户端传来的消息内容
     * @return java.lang.String
     **/
    @OnMessage
    public String onMessage(String text){
        log.info("接受到一条消息:"+text);
        return "已经接收到消息";
    }
    /**
     * 连接关闭时触发方法
     * @author liukang
     * @date 20:21 2024/5/18
     * @param session 每一个websocket的链接 对于服务端都是一个session
     **/
    @OnClose
    public void onClose(Session session){
        sessionMap.remove(session.getId());
        log.info(("websocket is close"));
    }

    /**
     * 定时任务模拟服务器给客户端主动发消息
     * @author liukang
     * @date 20:24 2024/5/18
     **/
    @Scheduled(fixedRate = 2000)  // fixedRate = 2000 每隔2s触发一次定时任务
    public void sendMessage() throws IOException {
        // 遍历sessionMap中的所有会话,给每个客户端都发送消息
        Set<String> keySet = sessionMap.keySet();
        for (String sessionId : keySet) {
            Session session = sessionMap.get(sessionId);
            RemoteEndpoint.Basic basicRemote = session.getBasicRemote();
            basicRemote.sendText("心跳");
        }
    }

}

5.启动类
由于第4点中,用spring内置的定时任务向客户端定时发送心跳,启动类上需要加上@EnableScheduling 注解,用于开启定时任务。

package com.etime;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @Author liukang
 * @Date 2022/7/4 11:32
 */
@EnableScheduling // 开启定时任务
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

2.客户端

新建一个vue文件,与服务端进行websocket 连接
代码示例如下:

<template>
  
  </template>
  
  <script>
  export default {
    name: 'HelloWorld',
    data () {
      return {
       
      }
    },

    mounted(){
        let ws = new WebSocket("ws://localhost:8090/myWs")
        ws.onopen = function(){
          console.log('open')
          ws.send("hello")
        }
        ws.onmessage = function(msg){
          console.log(msg.data)
        }
        ws.onclose = function(){
          console.log('close')
        }

    },
  }
  </script>
  

  <style scoped>
  
  </style>
  

注: 此处的ws://localhost:8090/myWs与服务端对应;myWs为后端websocket终端类中@ServerEndpoint(“/myWs”)定义的值

   let ws = new WebSocket("ws://localhost:8090/myWs")

3.效果展示

访问前端的vue页面,效果如下:
客户端控制台:
在这里插入图片描述

服务端控制台:
在这里插入图片描述

  • 40
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值