2015-01-31 2 views
14

Я пытаюсь использовать Spring с websocket. Я начал свое расследование с this tutorial.Как отправить сообщение клиенту с помощью websocket с использованием Spring

В моей стороне клиента У меня есть что-то подобное, чтобы инициализировать соединение с сервером:

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"); 
    } 
} 

Метод PhotoController.fireGreeting называется, как я хочу, но ничего не произошло на стороне клиента. Любые предложения? Спасибо.

+9

Пожалуйста, прочтите [21.4.5 Отправка сообщения] (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/ websocket.html # websocket-stomp-handle-send) из учебника Spring Websocket. Это, конечно, не так, как вы это делаете. Также подумайте о том, чтобы прочитать о Spring [механизм планирования] (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableScheduling.html) вместо использования необработанных потоков (неправильно) , –

+0

Спасибо за ссылку, это именно то, что я хочу сделать. О теме, которую я использую, очевидно, я не буду использовать ее в конечном состоянии моего приложения. У меня долгий процесс на стороне сервера, который отправит информацию клиенту, чтобы сообщить ему, какие шаги уже выполнены. – cheb1k4

ответ

30

Я смог решить свою проблему благодаря @Boris the Spider. Правильное решение сделать что-то вроде этого:

@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")); 
    } 
} 
+0

Спасибо, ты меня запомнишь. –

+0

Извините, это подход безопасности потока? – LeafiWan