io.sevenluck.chat.websocket.ChatWebSocketHandler.java Source code

Java tutorial

Introduction

Here is the source code for io.sevenluck.chat.websocket.ChatWebSocketHandler.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package io.sevenluck.chat.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.sevenluck.chat.domain.ChatChannel;
import io.sevenluck.chat.domain.ChatMember;
import io.sevenluck.chat.domain.ChatMessage;
import io.sevenluck.chat.domain.ChatRoom;
import io.sevenluck.chat.domain.ChatSession;
import io.sevenluck.chat.mapper.ChatMessageMapper;
import io.sevenluck.chat.repository.ChatChannelRepository;
import io.sevenluck.chat.repository.ChatMessageRepository;
import io.sevenluck.chat.repository.ChatRoomRepository;
import io.sevenluck.chat.repository.ChatSessionRepository;
import io.sevenluck.chat.websocket.domain.ChatMessageDTO;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 *
 * @author loki
 */
public class ChatWebSocketHandler extends TextWebSocketHandler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private ChatMessageRepository chatMessageRepository;
    private ChatSessionRepository chatSessionRepository;
    private ChatRoomRepository chatroomRepository;
    private ChatChannelRepository chatChannelRepository;

    List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    Map<String, SessionItem> sessionMap = new ConcurrentHashMap<>();

    public ChatWebSocketHandler() {
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.info("afterConnectionEstablished from ip " + session.getRemoteAddress().getAddress());

        final String token = (String) session.getAttributes().get(HttpAuthTokenHandShakeInterceptor.X_TOKEN);
        List<ChatSession> chatSessions = chatSessionRepository.findByAuthtoken(token);
        if (!sessions.isEmpty()) {
            logger.info("chatsession {} assigned to token {}", chatSessions.get(0), token);
            this.sessionMap.put(token, new SessionItem(chatSessions.get(0), session));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        final String myToken = (String) session.getAttributes().get(HttpAuthTokenHandShakeInterceptor.X_TOKEN);

        logger.info("handleTextMessage with message {} and token {}", message, myToken);
        String payload = message.getPayload();

        try {
            ObjectMapper mapper = new ObjectMapper();
            ChatMessageDTO chatMessage = mapper.readValue(payload, ChatMessageDTO.class);

            final ChatRoom room = findChatRoom(chatMessage);
            if (null == room)
                return;

            chatMessageRepository.save(newInstance(session, room, chatMessage));
            List<ChatChannel> channels = chatChannelRepository.findByChatRoom(room);

            for (ChatChannel channel : channels) {

                List<ChatSession> chatSessions = chatSessionRepository.findByMember(channel.getMember());
                for (ChatSession chatSession : chatSessions) {

                    if (!myToken.equals(chatSession.getAuthtoken())
                            && sessionMap.containsKey(chatSession.getAuthtoken())) {
                        WebSocketSession wsSession = sessionMap.get(chatSession.getAuthtoken()).getSession();
                        final String stringifyJSONObject = mapper.writeValueAsString(chatMessage);
                        wsSession.sendMessage(new TextMessage(stringifyJSONObject));
                    }
                }
            }

        } catch (Exception e) {
            logger.error("TAG", e);
        }
    }

    private ChatMessage newInstance(WebSocketSession wsSession, ChatRoom room, ChatMessageDTO chatMessage) {

        final String token = (String) wsSession.getAttributes().get(HttpAuthTokenHandShakeInterceptor.X_TOKEN);
        final ChatMember author = sessionMap.get(token).getChatSession().getMember();
        ChatMessage message = ChatMessageMapper.toEntity(chatMessage);
        message.setAuthor(author);
        message.setChatRoom(room);

        return message;
    }

    private ChatRoom findChatRoom(ChatMessageDTO chatMessage) {
        return chatroomRepository.findOne(chatMessage.getChatroomId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        final String token = (String) session.getAttributes().get(HttpAuthTokenHandShakeInterceptor.X_TOKEN);

        logger.info("afterConnectionClosed with token {} and cause {}", token, status.getReason());
        if (sessionMap.containsKey(token)) {
            sessionMap.remove(token);
        } else {
            logger.info("could not find any websession for token {}", token);
        }
    }

    @Autowired
    public void setChatChannelRepository(ChatChannelRepository chatChannelRepository) {
        this.chatChannelRepository = chatChannelRepository;
    }

    @Autowired
    public void setChatRoomRepository(ChatRoomRepository chatroomRepository) {
        this.chatroomRepository = chatroomRepository;
    }

    @Autowired
    public void setMessageRepository(ChatMessageRepository chatMessageRepository) {
        this.chatMessageRepository = chatMessageRepository;
    }

    @Autowired
    public void setChatSessionRepository(ChatSessionRepository chatSessionRepository) {
        this.chatSessionRepository = chatSessionRepository;
    }

    public class SessionItem implements Serializable {
        private final ChatSession chatSession;
        private final WebSocketSession session;

        public SessionItem(ChatSession chatSession, WebSocketSession session) {
            this.chatSession = chatSession;
            this.session = session;
        }

        public ChatSession getChatSession() {
            return chatSession;
        }

        public WebSocketSession getSession() {
            return session;
        }
    }

}