使用WebSocket对接JAVA和VUE过程中遇到的问题

在项目中要实现一个功能点,后端解析InputStream中的数据时同步发送到前端,因此需要使用WebSocket,记录一下开发过程中遇到的问题。

一 WebSocket常用方法类

package com.ai.server.util;

import com.ai.server.service.impl.DataService;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
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.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@Component  // 交给IOC容器
@ServerEndpoint("/webSocket")
public class WebSocketService {
    // 定义属性
    private Session session;
    //创建一个set用来存储用户
    private static CopyOnWriteArraySet<WebSocketService> websockets = new CopyOnWriteArraySet<>();
    /**
     * 当有用户创建连接时候调用该方法
     */
    @OnOpen
    public void onOpen(Session session) {
        // 给当前的Session赋值
        this.session = session;
        // 将当前对象添加到CopyOnWriteArraySet 中
        websockets.add(this);
        // 可以获取该session,但是其实也是一个内存地址
        System.err.println("【建立连接】 用户为:" + this.session);
        // 获取总数,这个不难理解,实际上这个集合的总数,就是WebSocket连接的总数
        System.err.println("【建立连接】 总数为:" + websockets.size());
    }

    /**
     * 有用户连接断开时候触发该方法
     */
    @OnClose
    public void onClose() {
        websockets.remove(this); // 将当前的对象从集合中删除
        System.err.println("【连接断开】 用户为:" + this.session);
        System.err.println("【连接断开】 总数为:" + websockets.size());
    }

    /**
     * 这个方法是客户端给服务端发送消息触发该方法
     * @param message : 消息内容
     */
    @OnMessage
    public void onMessage(String message) throws JSONException {
        System.err.println("【收到客户端发的消息】:" + message);
    }

    /**
     * 发送消息的方法,方便后期别的service调用
     *
     * @param message 消息内容
     */
    public void sendMessage(String message) {
        for (WebSocketService websocket : websockets) {   // 遍历该Set集合
            System.err.println("广播消息 【给用户】 :" + websocket + "发送消息" + "【" + message + "】"); // 获取一个,在控制台打印一句话
            try {
                websocket.session.getBasicRemote().sendText(message); // 发送消息的方法
            } catch (IOException e) {
                e.getMessage();
            }
        }
    }
}

二 WebSocket配置类
只有方法类的时候是无法成功调用的,需要有配置类

package com.ai.server.util;

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

@Configuration
public class WebSocketConfig {
    /**
     * 注入ServerEndpointExporter,
     * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

三 WebSocket类中调用其他应用层方法
在WebSocket类中直接自动注入是无效的,@Resource和@Autowire都不行,在实例化之后以及调用的时候该应用层类对象为null。
查阅资料了解到由于WebSocket容器是多对象,springboot容器是单例,因此WebSocket容器相对于springboot容器是独立的,不在springboot容器管理下,所以用普通的自动注入会失效。

	private static DataService dataService;

    @Autowired
    public void setChatService(DataService dataService) {
        WebSocketService.dataService = dataService;
    }

需要先实例化成静态类再注入。

四 前台部分

data() {
    return {
      websocket: null,
      messages: ''
    }
  },
mounted() {
    this.websocket = new WebSocket('ws://localhost:8080/webSocket')
    console.log(this.websocket)
    // 监听WebSocket连接打开事件
    this.websocket.onopen = () => {
      console.log('WebSocket connected')
    }
    // 监听WebSocket消息
    this.websocket.onmessage = (event) => {
      console.log(event.data)
      // 处理接收到的消息,比如更新界面等操作
      this.message = event.data
    }
    // 监听WebSocket关闭事件
    this.websocket.onclose = () => {
      console.log('WebSocket disconnected')
    }
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值