spring chat(二)

来源:互联网 发布:淘宝怎么不能图片搜索 编辑:程序博客网 时间:2024/04/27 21:40
参考资料:
1.http://spring.io/blog/2012/05/16/spring-mvc-3-2-preview-chat-sample/
2.spring redis Message-Driven相关资料(比如http://blog.csdn.net/xiejx618/article/details/41413417)


本文是spring chat(一)的延伸,加入redis,以致可以进行多台服务器的分布式部署.

1.spring mvc的Root Config配置AppConfig.

@Configuration@ComponentScan(basePackages={"org.exam.repository","org.exam.handler"})@PropertySource("classpath:redis.properties")public class AppConfig {    @Autowired    private Environment env;    @Bean    public RedisConnectionFactory redisConnectionFactory() {        JedisConnectionFactory cf = new JedisConnectionFactory();        cf.setHostName(this.env.getProperty("redis.host"));        cf.setPort(this.env.getProperty("redis.port", int.class));        cf.setPassword(this.env.getProperty("redis.password"));        return cf;    }    @Bean    public StringRedisTemplate redisTemplate() {        return new StringRedisTemplate(redisConnectionFactory());    }    @Bean    public RedisMessageListenerContainer redisMessageListenerContainer(MessageHandler messageHandler) {        RedisMessageListenerContainer mlc = new RedisMessageListenerContainer();        mlc.setConnectionFactory(redisConnectionFactory());        mlc.addMessageListener(messageHandler, new PatternTopic("chat"));        return mlc;    }}
这里注册了3个bean,连接redis服务器的工厂,redis收发信息工具和注册一个Redis客户端监听器.
2.上面这个监听器使用MessageHandler作为消息处理.内容如下:
@Componentpublic class MessageHandler implements MessageListener {    @Autowired    private ChatRepository chatRepository;    private final Map<DeferredResult<List<String>>, Integer> chatRequests =            new ConcurrentHashMap<DeferredResult<List<String>>, Integer>();    public Map<DeferredResult<List<String>>, Integer> getChatRequests() {        return chatRequests;    }    @Override    public void onMessage(Message message, byte[] pattern) {        for (Map.Entry<DeferredResult<List<String>>, Integer> entry : this.chatRequests.entrySet()) {            List<String> messages = this.chatRepository.getMessages(entry.getValue());            entry.getKey().setResult(messages);        }    }}
实现MessageListener接口的onMessage方法,即一旦redis客户端接收到消息,马上将相应的消息返回给现有未处理的request,并提交响应.ChatRepository注入的是RedisChatRepository(详细看:https://github.com/rstoyanchev/spring-mvc-chat/blob/redis/src/main/java/org/springframework/samples/async/chat/RedisChatRepository.java)此工具实现了发信息,获取信息的功能.消息的存储在redis.
3.再看看Controller的改变.
@Controller@RequestMapping("/mvc/chat")public class ChatController {    @Autowired    private MessageHandler messageHandler;    @Autowired    private ChatRepository chatRepository;    @RequestMapping(method = RequestMethod.GET)    @ResponseBody    public DeferredResult<List<String>> getMessages(@RequestParam int messageIndex) {        final DeferredResult<List<String>> deferredResult = new DeferredResult<List<String>>(null, Collections.emptyList());        final Map<DeferredResult<List<String>>, Integer> chatRequests = messageHandler.getChatRequests();        chatRequests.put(deferredResult, messageIndex);        deferredResult.onCompletion(new Runnable() {            @Override            public void run() {                chatRequests.remove(deferredResult);            }        });        List<String> messages = chatRepository.getMessages(messageIndex);        if (!messages.isEmpty()) {            deferredResult.setResult(messages);        }        return deferredResult;    }    @RequestMapping(method = RequestMethod.POST)    @ResponseBody    @ResponseStatus(value = HttpStatus.OK)    public void postMessage(@RequestParam String message) {        chatRepository.addMessage(message);    }}
改变不大,可以将请求放入到messageHandler的chatRequests,也可以从chatRequests取出未处理的请求.chatRepository用于发送消息或获取消息.post方法把处理那些未处理的请求代码去掉了,我觉得没必要.只要在redis监听到消息马上处理,基本就没什么延迟了.
4.页面与前文一样,不作任何改变.启动redis,然后测试.


0 0
原创粉丝点击