package com.pingpang.redis;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pingpang.util.StringUtil;
import com.pingpang.websocketchat.ChannelManager;
import com.pingpang.websocketchat.Message;
import com.pingpang.websocketchat.send.impl.ChatSendUtil;

@Configuration
public class RedisListener {

	// 日志操作
    protected Logger logger = LoggerFactory.getLogger(RedisListener.class);
	
    
    //表示监听一个频道
   	/**
	 * redis消息监听器容器
	 * 可以添加多个监听不同话题的redis监听器，只需要把消息监听器和相应的消息订阅处理器绑定，该消息监听器
	 * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
	 * @param connectionFactory
	 * @param listenerAdapter
	 * @return
	 */
	//MessageListenerAdapter 表示监听频道的不同订阅者
	@Bean
	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter){
	     RedisMessageListenerContainer container = new RedisMessageListenerContainer();
	    container.setConnectionFactory(connectionFactory);
	    //订阅多个频道
	    container.addMessageListener(listenerAdapter,new PatternTopic(RedisPre.SEND_MSG));
	    //序列化对象（特别注意：发布的时候需要设置序列化；订阅方也需要设置序列化）
	    Jackson2JsonRedisSerializer  seria = new Jackson2JsonRedisSerializer (Object.class);
	    
	    ObjectMapper mapper = new ObjectMapper();
   		//将类名称序列化到json串中，去掉会导致得出来的的是LinkedHashMap对象，直接转换实体对象会失败
   		//mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); 	    //设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
   		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	    
	    seria.setObjectMapper(mapper);
	    container.setTopicSerializer(seria);
	    
	    return container;
	}
    
    
	// 表示监听一个频道
	@Bean
	public MessageListenerAdapter listenerAdapter(RedisListener receiver) {
		// 这个地方 是给messageListenerAdapter 传入一个消息接受的处理器，
		return new MessageListenerAdapter(receiver, "chatMsg");
	}

	/**
	 * 监听发送消息
	 * 
	 * @param str
	 * @throws Exception 
	 */
	public void chatMsg(String str) throws Exception {

		if (!StringUtil.isNUll(str)) {
			logger.info("获取数据:" + str);
			ObjectMapper mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
			// 设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			Message message = mapper.readValue(str, Message.class);
			if (ChannelManager.isExitChannel(message.getAccept())) {
				ChatSendUtil.getChatSend(message);
			}
		}

	}
}
