Cannot deploy POJO class [X.X.X.X.WebSocketService$$SpringCGLIB$$0] as it is not

第一次接触websocket,不知道websocket是什么东西。要写一个后端向前端发送消息的任务。公司的大哥介绍了这篇文章,代码很简单。

注册使用bean 用来扫描端点

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author guoyufeng
 * 注册baen来扫描端点
 */

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

配置端点,WebSocket服务端


import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author guoyufeng
 * webSovket建立连接
 */

@Component
@ServerEndpoint("/webSocket/{userId}")
public class WebSocketService {
    Logger log = LoggerFactory.getLogger(getClass());

    /**用来存放每个客户端对应的MyWebSocket对象。*/
    public static ConcurrentHashMap<String,WebSocketService> webSocketMap = new ConcurrentHashMap<>();

    /**与某个客户端的连接会话*/
    private Session session;

    /**接收userId*/
    private String userId="";


    /**
     * 连接建立成功调用的方法
     * */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, this);
            //加入set中
        } else {
            webSocketMap.put(userId, this);
        }

        System.out.println(webSocketMap+"--------------------------------");

    }

        /**
         * 服务器主动推送到客户端
         */
        public void sendMessage(String message) {
            try {
                this.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        /**
         * 收到客户端消息后 --- 自动调用的方法
         *
         * @param message 客户端发送过来的消息*/
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("用户消息:"+userId+",报文:"+message);
        }


        /**
         * 客户端关闭 -- 连接关闭自动回调的方法
         */
        @OnClose
        public void onClose() {
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                //从set中删除
                //subOnlineCount();
            }
            log.info("客户端关闭");
        }
}

然后在启动的时候,报这个错误

Cannot deploy POJO class [net.shengjian.metaid.config.WebSocketService$$SpringCGLIB$$0] as it is not annotated with @ServerEndpoint

在网上搜解决方法,搜了两个

1.这位大佬的文章,可能是我比较菜,没有解决。但是问题确实是这个问题。

2.是这位大佬的这篇文章,这个可以启动,但是长连接的时候,连接不上。

最后请教别人,发现问题。

Spring管理采用单例模式(singleton),而 WebSocket 是多对象的,即每个客户端对应后台的一个 WebSocket 对象,也可以理解成 new 了一个 WebSocket,这样当然是不能获得自动注入的对象了,因为这两者刚好冲突。

可以得出结论,没有注入。

然后想到了有个单例变多例的注解。

@Scope("prototype")

在设置端口的类上加上之后,竟然可以启动成功,并且长连接成功。

完整代码



import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author guoyufeng
 * webSovket建立连接
 */

@Component
@Scope("prototype")
@ServerEndpoint("/webSocket/{userId}")
public class WebSocketService {
    Logger log = LoggerFactory.getLogger(getClass());

    /**用来存放每个客户端对应的MyWebSocket对象。*/
    public static ConcurrentHashMap<String,WebSocketService> webSocketMap = new ConcurrentHashMap<>();

    /**与某个客户端的连接会话*/
    private Session session;

    /**接收userId*/
    private String userId="";


    /**
     * 连接建立成功调用的方法
     * */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, this);
            //加入set中
        } else {
            webSocketMap.put(userId, this);
        }

    }

        /**
         * 服务器主动推送到客户端
         */
        public void sendMessage(String message) {
            try {
                this.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        /**
         * 收到客户端消息后 --- 自动调用的方法
         *
         * @param message 客户端发送过来的消息*/
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("用户消息:"+userId+",报文:"+message);
        }


        /**
         * 客户端关闭 -- 连接关闭自动回调的方法
         */
        @OnClose
        public void onClose() {
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                //从set中删除
                //subOnlineCount();
            }
            log.info("客户端关闭");
        }
}

向前端发送消息调用其sendMessage方法就可以了

WebSocketService webSocketService = WebSocketService.webSocketMap.get(owner);
                        if (webSocketService != null){
                           webSocketService.sendMessage("Registration successful!");
                        }

成功!!!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值