如何使用Spring通过websocket向客户端发送消息

如何使用Spring通过websocket向客户端发送消息,spring,sockjs,spring-websocket,Spring,Sockjs,Spring Websocket,我尝试将弹簧与websocket一起使用。我的调查是从一开始的 在我的客户端中,我有类似的功能来初始化与服务器的连接: function connect() { var socket = new SockJS('/myphotos/form'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); co

我尝试将弹簧与websocket一起使用。我的调查是从一开始的

在我的客户端中,我有类似的功能来初始化与服务器的连接:

function connect() {
    var socket = new SockJS('/myphotos/form');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function(frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function(greeting){
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}
它工作得很好,在我的控制器中,我能够在以下课程中完成我的过程:

@Controller
@RequestMapping("/")
public class PhotoController {

    @MessageMapping("/form")
    @SendTo("/topic/greetings")
    public Greeting validate(AddPhotosForm addPhotosForm) {
        return new Greeting("Hello world !");
    }
}
现在我想做的是让一个线程发送一条消息给正在收听“/topic/greeting”的客户机。我这样编写了我的Runnable类:

public class FireGreeting implements Runnable {

    private PhotoController listener;

    public FireGreeting(PhotoController listener) {
        this.listener = listener;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep( 2000 );
                listener.fireGreeting();
            } catch ( InterruptedException e ) {
                e.printStackTrace();
            }
        }   
    }
}
这样完成了我的控制器:

@Controller
@RequestMapping("/")
public class PhotoController {

    @MessageMapping("/form")
    @SendTo("/topic/greetings")
    public Greeting validate(AddPhotosForm addPhotosForm) {

        // added this part
        FireGreeting r = new FireGreeting( this );
        new Thread(r).start();

        return new Greeting("Hello world !");
    }

    // added this method
    @SendTo("/topic/greetings")
    public Greeting fireGreeting() {
        System.out.println("Fire");
        return new Greeting("Fire");
    }
}
@Controller
@RequestMapping("/")
public class PhotoController {

    @Autowired
    private SimpMessagingTemplate template;

    @MessageMapping("/form")
    @SendTo("/topic/greetings")
    public Greeting validate(AddPhotosForm addPhotosForm) {

        FireGreeting r = new FireGreeting( this );
        new Thread(r).start();

        return new Greeting("Hello world !");
    }

    public void fireGreeting() {
        System.out.println("Fire");
        this.template.convertAndSend("/topic/greetings", new Greeting("Fire"));
    }
}
方法PhotoController.firehreeting按我所希望的方式调用,但在客户端没有发生任何事情。
有什么建议吗?谢谢。

多亏了@Boris the Spider,我才能够解决我的问题。正确的解决方案是这样做:

@Controller
@RequestMapping("/")
public class PhotoController {

    @MessageMapping("/form")
    @SendTo("/topic/greetings")
    public Greeting validate(AddPhotosForm addPhotosForm) {

        // added this part
        FireGreeting r = new FireGreeting( this );
        new Thread(r).start();

        return new Greeting("Hello world !");
    }

    // added this method
    @SendTo("/topic/greetings")
    public Greeting fireGreeting() {
        System.out.println("Fire");
        return new Greeting("Fire");
    }
}
@Controller
@RequestMapping("/")
public class PhotoController {

    @Autowired
    private SimpMessagingTemplate template;

    @MessageMapping("/form")
    @SendTo("/topic/greetings")
    public Greeting validate(AddPhotosForm addPhotosForm) {

        FireGreeting r = new FireGreeting( this );
        new Thread(r).start();

        return new Greeting("Hello world !");
    }

    public void fireGreeting() {
        System.out.println("Fire");
        this.template.convertAndSend("/topic/greetings", new Greeting("Fire"));
    }
}

按照@Boris thespider的建议,安排周期性任务的更好方法是使用Spring调度机制(请参阅)

为了分离关注点,我还将计划相关代码与控制器代码分离

在您的情况下,可以使用如下类:

@Component
public class ScheduledTasks {

    @Autowired
    private SimpMessagingTemplate template;

    @Scheduled(fixedRate = 2000)
    public void fireGreeting() {
        this.template.convertAndSend("/topic/greetings", new Greeting("Fire"));
    }
}

并将
@EnableScheduling
标记添加到应用程序类。

请阅读SpringWebSocket教程。你肯定不是这样做的。还考虑阅读Spring而不是使用原始线程(不正确)。谢谢链接,这正是我想要做的。关于我使用的线程,很明显,我不会在应用程序的最终状态中使用它。我在服务器端有一个很长的过程,它会向客户端发送信息,让客户端知道已经完成了哪些步骤。哪个
MessageChannel
类正在与注入的
SimpMessagingTemplate
一起使用?