WebSockets JSR 356 Spring 集成 @ServerEndpoint

3
问题:@ServerEndpoint类中的@Autowired bean为null
如何确保下面的WebSocketController类将被注入bean,也就是说,如何使其由Spring管理?我可以连接到websocket,所以它是工作正常的,但是WebSocketController类实例中的gameService始终为null,因此我认为它是由tomcat某种方式创建而不是Spring。
我正在使用Spring Boot。我只需要弄清楚如何将bean注入到这个websocket控制器类中。
WebSocketController类
@Component
@ServerEndpoint("/sock")
public class WebSocketController {

    @Autowired
    private GameService gameService;

    private static Set<Session> clients = Collections.synchronizedSet(new HashSet<Session>());

    @OnMessage
    public void handleMessage(Session session, String message) throws IOException {

        session.getBasicRemote().sendText(
                "Reversed: " + new StringBuilder(message).reverse());
    }

    @OnOpen
    public void onOpen(Session session) {
        clients.add(session);
        System.out.println("New client @"+session.getId());
        if (gameService == null) System.out.println("game service null");
    }

    @OnClose
    public void onClose(Session session) {
        clients.remove(session);
        System.out.println("Client disconnected @" + session.getId());
    }
}

游戏服务接口和实现

public interface GameService {
    List<Character> getCharacters();
}

@Service
public class GameServiceMockImpl implements GameService {

    @Override
    public List<Character> getCharacters() {
        List<Character> list = new ArrayList<>();
        list.add(new Character("aaa","1.png",100));
        list.add(new Character("aaa","2.jpg",100));
        list.add(new Character("aaa","3.jpg",100));
        return list;
    }
}

应用程序类
@SpringBootApplication
public class App  {

    public static void main(String args[]){
        SpringApplication.run(App.class,args);
    }

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

}

编辑:

使用Spring 4的WebSockets完全无法使用,我甚至无法通过浏览器连接。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}


public class MyHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println(message.getPayload());
    }

}
2个回答

3
您正在尝试集成Spring和Java WebSocket API。一个被注解为@Component的类被注册为Spring bean,它的实例由Spring管理,但是如果一个类被注解为@ServerEndpoint,它将被注册为服务器端WebSocket端点,并且每当对应的端点的WebSocket连接到服务器时,它的实例将由JWA实现创建和管理。您不能同时使用这两个注解。
您可以使用CDI注入(您的服务器也应该支持)。
@ServerEndpoint("/sock")
public class WebSocketController {

    @Inject
    private GameService gameService;

或者看一下这个文档:Spring 4支持WebSocket。

谢谢回答。我宁愿使用Spring 4 WebSocket,并且我想使用“直接方法”而不是SockJS等等。因此,我创建了TextWebSocketHandler和WebSocketConfigurer。但是它不起作用。我无法从浏览器连接。控制台中显示已将给定的URL映射到文本处理程序,但仍无法连接。我在主帖中添加了代码。 - Greyshack
1
我不得不允许来自其他来源的连接,现在它可以工作了。所以最终我使用了Spring 4的Websockets。 - Greyshack
1
但这只是为了测试。最终所有东西都会在服务器上。 - Greyshack

3
也许这篇文章能帮到您:

https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support

,如果您的Spring版本是4或以上,则可以使用该依赖。
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${spring.version}</version>
</dependency>

然后只需简单地执行以下步骤:
@ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class)
public class WebSocketEndpoint {

    @Inject
    private BroadcastService broadcaster;

好又容易。这就是让我成功的方法! - LordOfThePigs
你能简要解释一下这段代码吗?我不太明白如何使用它。 - susan097
@Sushant 你可以阅读这篇文章 https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support - 所有的解释都在那里以最佳形式呈现。 - lanwen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接