在Spring中使用Web套接字创建活动源

时间:2017-12-03 22:19:27

标签: java spring sockets spring-boot

我有一个仪表板,显示最新输入的用户以及我在这些服务中获得的一些其他信息:

@JsonView(View.SurveyWithClients.class)
@RequestMapping(value="getData/{gender}",method=RequestMethod.GET)
public @ResponseBody List<Info> getTopUsers(@PathVariable("gender") char gender) {
    List<Info> info=infoService.findByClient_GenderOrderByInfoResults(gender);
    return info;

}

这一个:

 @JsonView(View.SurveyWithClients.class)
@RequestMapping(value="getActivityFeed",method=RequestMethod.GET)
public @ResponseBody List<Info> getLatestActivity() {
    return infoService.findTop5ByOrderBySubmittedDateDesc();

}

我目前正在做的是,我对这两个端点进行ajax调用,并将数据显示在div中。 但我读到的更好的解决方案是使用网络套接字,以便实时更新视图。

是我需要传递的端点还是服务层? 代码的结构如何?实现这一目标的逻辑路径是什么? 我只看过他们用于聊天应用程序的例子,但我不知道如何使用这样的计算和数据。 任何指导表示赞赏

1 个答案:

答案 0 :(得分:0)

如果你在谈论你的饲料网络套接字的双向通道是有意义的,如果你在谈论1种方式它也有意义,但你需要记住,还有许多其他趋势可以使用HTTP。

当使用websocket你使用不同的协议(不是HTTP)时,将使用HTTP建立连接,但之后将打开websocket以便与HTTP协议分离的通信,这在我看来特别好,浏览器有限能够进行并发HTTP请求。

我在本文中提到了使用websocket和消息代理创建feed的方法 Designing Complex Notification system in spring

您只需要包含websock依赖

https://mvnrepository.com/artifact/org.springframework/spring-websocket/5.0.2.RELEASE

您还需要在spring应用程序中配置websocket

@Configuration
@EnableWebSocket
public class WebSocketConfig  implements WebSocketConfigurer{

    @Autowired
    private NotificationHandler notificationHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        System.out.println("handler registered for websocket");
        registry.addHandler(notificationHandler,  "/questions")//define the endpoint for the websocket with handler to all the messages
        .setAllowedOrigins("*").withSockJS(); //allow CRSF

    }

我的处理程序用于推送到特定客户端

@Component
public class NotificationHandler extends TextWebSocketHandler {

    private Map<Integer, WebSocketSession> sessions = new ConcurrentHashMap<>();
    private Map<String, List<Integer>> userToSessionMap = new ConcurrentHashMap<>();

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private NotificationService notificationService;

    @Value("${jwt.header}")
    private String tokenHeader;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(Integer.valueOf(session.getId()), session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println("Session Id: " + session.getId());
        System.out.println("Session Id: " + session.getId());

        System.out.println("Extracted session ID " + sessions.get(Integer.valueOf(session.getId())).getId());
         String username = jwtTokenUtil.getUsernameFromToken(message.getPayload());
         if(username == null || username.isEmpty()) {
             return;
         } else if(!userToSessionMap.containsKey(username)) {
             userToSessionMap.put(username, new ArrayList<Integer>());
             userToSessionMap.get(username).add(Integer.valueOf(session.getId()));
         } else if(!userToSessionMap.get(username).contains(Integer.valueOf(session.getId()))) {
             userToSessionMap.get(username).add(Integer.valueOf(session.getId()));
         }

         try {
            sessions.get(Integer.valueOf(session.getId())).sendMessage(new TextMessage("new message recieved"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void sendMessageToUserSessions(User user, String message) {
        Notification notification = notificationService.createNotification(user, message);
        List<Integer> sessionsList = userToSessionMap.get(user.getUsername());
        if(sessionsList == null || sessionsList.isEmpty())//no available sessions (makes no sense, need to check with UI)
            return;
        for(Integer sessionId: sessionsList) {
            WebSocketSession session = sessions.get(sessionId);
            if(session != null)
                try {
                    session.sendMessage(new TextMessage(notification.toJsonString()));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                };
        }
    }

}