WebSocket前后端交互

SpringBoot/SpringCloud整合WebSocket

引入WebSocket Jar包

		<!--WebSocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

WebSocket 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
 * @description:WebSocket 配置类
 * @author: gxz
 * @create: 2024/5/8
 */
@Configuration
public class WebSocketConfig {
	/**
     * 给spring容器注入这个ServerEndpointExporter对象
     * 相当于xml:
     * <beans>
     * <bean id="serverEndpointExporter" class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>
     * </beans>
     * <p>
     * 检测所有带有@serverEndpoint注解的bean并注册他们。
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointConfigurator(){
        return new ServerEndpointExporter();
    }
    //如果打包成jar包运行,bean注入这个配置类,war包的不需要。
}

WebSocket 处理类

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @description:WebSocket 处理类
 * @author: gxz
 * @create: 2024/5/8 15:44
 */
@Component
    @ServerEndpoint("/webSocket/{uId}")
@Slf4j
public class WebSocketServerUtil {
    /**
     * 与某个客户端的连接对话,需要通过它来给客户端发送消息
     */
    private Session session;
    /**
     * 用于存所有的连接服务的客户端,这个对象存储是安全的
     */
    private static CopyOnWriteArraySet<WebSocketServerUtil > webSocketSet = new CopyOnWriteArraySet<>();
    /**
     * 用于存所有的连接第三方ws服务的客户端
     */
    private static ConcurrentHashMap<Long,WebSocketServerUtil > webSocketMap = new ConcurrentHashMap<>();
    /**
     * 标识当前连接客户端的用户名
     */
    private Long uId = null;


    @OnOpen
    public void onOpen(Session session, @PathParam("uId") Long uId){
        this.session = session;
        this.uId = uId;
        if(webSocketMap.containsKey(uId)){
            webSocketMap.remove(uId);
            webSocketMap.put(uId,this);
        }else{
            webSocketMap.put(uId,this);
            webSocketSet.add(this);
        }
        log.info("【websocket消息】有新的连接,总数:{}",webSocketMap.size());
    }

    @OnClose
    public void onClose(){
        if(webSocketMap.containsKey(uId)){
            webSocketMap.remove(uId);
            //从set中删除
            webSocketSet.remove(this);
        }
        log.info("【websocket消息】连接断开,总数:{}",webSocketSet.size());
    }

    @OnMessage
    public void onMessage(String message){
        log.info("【websocket消息】收到客户端发来的消息:{}",message);
    }

    public void sendMessage(String message){
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    /**
     * 发送自定义消息
     * */
    public static void sendInfo(String message,Long uId) throws Exception {
        log.info("发送消息到:"+uId+",报文:"+message);
        if(webSocketMap.containsKey(uId)){
            webSocketMap.get(uId).sendMessage(message);
        }else{
            log.error("用户"+uId+",不在线!");
            throw new Exception("连接已关闭,请刷新页面后重试");
        }

    }
}

WebSocket 发送消息

	Long uId = new Long("1");
    Map msgMap = new HashMap();
    msgMap.put("step",1);
    msgMap.put("type",2);
    msgMap.put("msg","hello");
    String s = JSONObject.toJSONString(msgMap);
    try {
        WebSocketServerUtil.sendInfo(s,uId);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

vue整合WebSocket

	/**
     * 初始化websocket连接
     */
    initWebSocket() {
      let uId = 1;
      let websocket = null;
      if (typeof WebSocket === "undefined") {
        alert("该浏览器不支持websocket!");
      } else {
        websocket = new WebSocket("ws://127.0.0.1:9206/webSocket/" + uId);
        websocket.onopen = function(event) {
          console.log("建立连接");
          websocket.send('Hello WebSockets!');
        }
        websocket.onclose = function(event) {
          console.log('连接关闭')
          // this.reconnect(); //尝试重连websocket
        }
        //建立通信后,监听到后端的数据传递
        websocket.onmessage = function(event) {
          let data = JSON.parse(event.data);
          //业务处理....
          if (data.step == 1) {
            alert(data.msg);
          }
        }
        websocket.onerror = function() {
          // notify.warn("websocket通信发生错误!");
          // initWebSocket()
        }
        window.onbeforeunload = function() {
          websocket.close();
        }
      }
    },
    // 重连
    reconnect() {
      console.log("正在重连");
      // 进行重连
      setTimeout(function() {
        this.initWebSocket();
      }, 1000);
    },

完成上述所有操作后,由于websocket接口没有token,所以要在拦截器白名单设置,不验证token

// 对于登录login 注册register 验证码captchaImage 允许匿名访问
                .antMatchers("/login", "/register", "/captchaImage","/loginByPhone"
                        ,"/webSocket/**","/app/api/login"
                ).anonymous()
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket前后端交互是指前端和后端之间通过WebSocket通信协议进行实时通信的过程。WebSocket协议是HTML5新提出的标准协议,其最大的优点就是能够实现双向的实时通信,通过它,在不使用HTTP的情况下,在客户端和服务端之间建立起一个持久连接,使得客户端可以直接向服务端发送消息,服务端也可以主动向客户端推送数据,而无需通过HTTP请求来实现。 前端使用WebSocket可以通过浏览器内置的WebSocket API来直接访问WebSocket服务端,从而与之进行通信。常见的WebSocket API包括:onopen、onmessage、onerror、和onclose等事件。其中,onopen表示WebSocket连接建立成功的事件,onmessage表示在接收到WebSocket数据时触发的事件,onerror表示WebSocket通信出现错误时触发的事件,onclose表示WebSocket连接关闭时触发的事件。 后端服务器通过WebSocket服务端的API操作,接收并处理客户端发送过来的数据,并根据业务需求向指定客户端发送数据,其中包括:send方法、onopen事件、onclose事件、onmessage事件等。在使用WebSocket服务端时,需要考虑如何处理多个客户端的连接,可以通过维护一个WebSocket连接列表来管理客户端的连接。 总之,WebSocket可以实现标准的前后端实时通信,具有以下特点:消息实时获取、消息推送效率高、数据传输安全性高,是一种较为实用的网络通信技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值