YeautyYE / netty-websocket-spring-boot-starter

:rocket: lightweight high-performance WebSocket framework ( 轻量级、高性能的WebSocket框架)
Apache License 2.0
1.81k stars 534 forks source link

我想用@Autowired注入WebSocket服务对象,却发现和@ServerEndpoint修饰的WebSocket服务对象不是同一个 #153

Open chenzhixiang111 opened 3 years ago

chenzhixiang111 commented 3 years ago

我的代码如下

@ServerEndpoint(path = "/websocket/{stationId}", port = "8000")
public class NettyWebSocketServer {
...
}

在另一个地方注入了这个对象

@Autowired
private NettyWebSocketServer nettyWebSocketServer;

但是通过debug我发现,注入的对象并不是我@ServerEndpoint声明的那个对象。要怎么才能注入我@ServerEndpoint声明的那个对象呢

YeautyYE commented 3 years ago

不能,因为每一条连接进来会new一个新的对象。 为什么要用@Autowired把它注入到别的地方

chenzhixiang111 commented 3 years ago

不能,因为每一条连接进来会new一个新的对象。 NettyWebSocketServer 不是单例的吗,我以为它是单例的,每一条连接会创建一个Session对象。

为什么要用@Autowired把它注入到别的地方

我在OnOpen方法里面保存了Session在Map中。代码如下:

    private final ConcurrentHashMap<Long, List<Session>> webSocketClientMap = new ConcurrentHashMap<>();
    @OnOpen
    public void onOpen(Session session, @PathVariable Long stationId) {
        List<Session> webSocketClientList = webSocketClientMap.get(stationId);
        if (webSocketClientList == null) {
            webSocketClientList = new CopyOnWriteArrayList<>();
        }
        webSocketClientList.add(session);
        webSocketClientMap.put(stationId, webSocketClientList);
        log.info("WebSocket服务连接成功, stationId= {}", stationId);
    }

并写了一个方法来主动推送消息:

    public void sendNotify(Long stationId, String notify) {
        List<Session> webSocketClientList = webSocketClientMap.get(stationId);
        if (webSocketClientList != null) {
                for (Session session : webSocketClientList) {
                    session.sendText(notify);
                }
        }

    }

我希望通过@AutoWired方式让别的对象获取到 NettyWebSocketServer的引用,并调用sendNotify方法,但是注入的对象并不是@ServerEndpoint(path = "/websocket/{stationId}", port = "8000") 修饰的那个NettyWebSocketServer 。这导致Map中没有任何Session

YeautyYE commented 3 years ago

map用static修饰就好,因为这个map并不属于这个对象,而是属于这整个项目,并且存有多个对象。 这样就可以通过NettyWebSocketServer. webSocketClientMap来拿到所有session 。