[开发心得]websocket vue springboot使用

前言: 这篇文章的名字为了方便百度搜索,显得不是很规整。

websocket 的相关概念,实现方式这里不做赘述,有一些场景,不适合前端长轮询。所以通常采用后端主动通知的方式。

Springboot部分:

版本号由官方“仲裁“获得:

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

websocket配置: (注意点:要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。)

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

@Configuration
public class WebSocketConfig {
    /**
     * 方法描述 Websocket配置
     * @since:
     * @param:  
     * @return: 
     * @author:
     * @date:
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

发布类:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: 
 * @Date: 
 * @Description:
 */
@Slf4j
@ServerEndpoint("/websocket/{username}")
@Component
public class WebSocketController {
    // 连接数
    private static int onlineCount = 0;
    private static Map<String,WebSocketController> clients =new ConcurrentHashMap<>();
    private Session session;
    private String username;
    /**
     * 方法描述  连接成功调用的方法
     * @since:
     * @param:  * @param username
     * @param session
     * @return: void
     * @author: 
     * @date:
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username,Session session){
        this.username = username;
        this.session = session;
        WebSocketController.onlineCount ++;
        log.info("响应新连接,当前连接数为:{}",onlineCount);
        clients.put(username,this);
    }
    @OnClose
    public void onClose(){
        clients.remove(username);
        WebSocketController.onlineCount--;
        log.info("发现客户端断开链接,当前连接数为:{}",onlineCount);
    }
    @OnMessage
    public void onMessage(String message){
        log.info("message:{}",message);
    }
    @OnError
    public void onError(Session session,Throwable throwable){
        log.error("ws eror:{}",throwable.getMessage());
    }
    // 消息群发
    public static void sendMessage(String message){
        for(WebSocketController item : clients.values()){
            item.session.getAsyncRemote().sendText(message);
        }
    }
    // 消息发送指定
    public static void sendMessagePoint(String message,Session session){
        session.getAsyncRemote().sendText(message);
    }
}

Vue部分:

十分要注意的地方就是,data里边要放一个websocket变量用来承接(类似的教程网上一大把,但是就是没人喜欢说这块):

data() {
    return {
        websocket: ''
    }
  }

该方法可以在created 或者 mounted钩子函数执行的时候调用,一般建议mounted,除非在构建页面的时候,需要立马与后端通信. 

另外,要注意,WebSocket无需额外引入,直接可以用的,但是要注意大小写区分问题:WebSocket

initWebSocket() {
    
      let socktUrl = 'ws://xxxx:8080/websocket/{' + this.username + '}';
      this.websocket = new WebSocket(socktUrl);
      this.websocket.onopen = this.open;
      this.websocket.onerror = this.error;
      this.websocket.onmessage = this.getMessage;
      this.websocket.onclose = this.close;
    },
    open() {
      console.log('socket连接成功')
    },
    error() {
      console.log('连接错误')
    },
    getMessage(msg) {
      // 从后端获取到消息1.确定是哪个素材的,如果素材在当页,就直接控制其进度条.后端需要给前端传递{id:"",process:""}类型的数据
      console.log('收到消息' + msg);
    },
    send() {
      this.socket.send()
    },
    close() {
      console.log('socket已经关闭')
    }
  },
  destroyed() {
    if (this.socket) {
      this.socket.close();
    }
  }

关于测试和调用.这里不做详解,后端可以专门写一个测试接口用来供给调用,用来处理后端给前端测试,如直接调用  WebSocketController.sendMessage()方法.是群发还是指定发给某台机器,需要根据业务来定.

 

posted @ 2021-04-22 18:37  虹梦未来  阅读(11)  评论(0编辑  收藏  举报  来源