基于订阅/发布模式的简易聊天室实现(java+redis)
2016-03-23 15:55
936 查看
对于本篇博文主要从以下两部分介绍简易聊天室的实现:
1.介绍redis发布订阅模式
2.java代码实现订阅发布模式
一、redis发布订阅模式
redis订阅分为订阅频道和订阅模式
1.订阅频道
打开一个客户端1,订阅电影直播频道:
在电影直播频道发布信息A
在消息发布后,订阅消息的客户端1就会收到发布的信息。如果我们想要订阅多个频道,可以使用订阅模式。
2.订阅模式
重新打开一个启客户端2,并订阅有关电影的模式:
此时在电影直播频道重新发布消息A,客户端1和客户端2都会收到发布的消息。
如果在电影历史频道发布消息B,
此时只有客户端2会收到消息。
订阅模式支持* 、? 、 []三种模式
*匹配后面所有的字符
?匹配一个字符
[]匹配中括号里的字符 h[eo]llo 匹配hello和hollo
二、java代码实现订阅发布模式
接下来使用Jedis实现一个简单的聊天室
我们用redis作为服务转发,所以没有服务端代码,只需要写客户端就可以了:
定义客户端,功能比较简单,进入房间提示、离开房间提示、在房间说话:
在上面的代码中有一个ChatSubscribe的类,该类为聊天室的动作监听类,在这个类中我们只定义订阅频道、取消订阅频道、接收消息方法:
接下来redis通用类的编写:
最后是主函数启动客户端了:
到此,一个简单的聊天室编写完成。
1.介绍redis发布订阅模式
2.java代码实现订阅发布模式
一、redis发布订阅模式
redis订阅分为订阅频道和订阅模式
1.订阅频道
打开一个客户端1,订阅电影直播频道:
127.0.0.1:6379> subscribe "movie::live::room"
在电影直播频道发布信息A
127.0.0.1:6379> publish movie::live::room "Does someone like snow white?"
在消息发布后,订阅消息的客户端1就会收到发布的信息。如果我们想要订阅多个频道,可以使用订阅模式。
2.订阅模式
重新打开一个启客户端2,并订阅有关电影的模式:
127.0.0.1:6379> psubscribe "movie*"
此时在电影直播频道重新发布消息A,客户端1和客户端2都会收到发布的消息。
如果在电影历史频道发布消息B,
127.0.0.1:6379> publish movie::history::room "Does someone like snow white?"
此时只有客户端2会收到消息。
订阅模式支持* 、? 、 []三种模式
*匹配后面所有的字符
?匹配一个字符
[]匹配中括号里的字符 h[eo]llo 匹配hello和hollo
二、java代码实现订阅发布模式
接下来使用Jedis实现一个简单的聊天室
我们用redis作为服务转发,所以没有服务端代码,只需要写客户端就可以了:
定义客户端,功能比较简单,进入房间提示、离开房间提示、在房间说话:
package redis.publishandsubscribe; import java.util.Scanner; import redis.RedisUtil; public class Client { private String name ; private ChatSubscribe roomSubListerner; public Client(){ roomSubListerner = new ChatSubscribe(); } public void setName(String name){ this.name =name; } public String getName(){ return name; } /* 进入房间*/ public void subscribe(final String[] room){ ChatSubscribe roomSub = roomSubListerner; roomSub.setClientName(name); roomSub.setRoom(room); RedisUtil.subscribe(room, roomSub); } /* 退出房间*/ public void unSubscribe(final String[] room){ roomSubListerner.unsubscribe(room); } /*说话*/ public void say(final String room,String message){ RedisUtil.publish(room, name+" say:"+message); } }
在上面的代码中有一个ChatSubscribe的类,该类为聊天室的动作监听类,在这个类中我们只定义订阅频道、取消订阅频道、接收消息方法:
package redis.publishandsubscribe; import redis.RedisUtil; import redis.clients.jedis.JedisPubSub; public class ChatSubscribe extends JedisPubSub{ /*成员名字*/ private String clientName; /*房间名*/ private String[] room; public String getClientName() { return clientName; } public void setClientName(String clientName) { this.clientName = clientName; } public String[] getRoom() { return room; } public void setRoom(String[] room) { this.room = room; } @Override public void onUnsubscribe(String channel, int subscribedChannels) { //do nothing } @Override public void onSubscribe(String channel, int subscribedChannels) { RedisUtil.publish( channel,clientName+ "进入房间"); } @Override public void onPUnsubscribe(String pattern, int subscribedChannels) { } @Override public void onPSubscribe(String pattern, int subscribedChannels) { } @Override public void onPMessage(String pattern, String channel, String message) { } @Override public void onMessage(String channel, String message) { System.out.println("收到来自"+channel+"房间的消息:"+message); } @Override public void unsubscribe(String... channels) { for(String c : channels) RedisUtil.publish(c, clientName+"离开房间"); super.unsubscribe(channels); } }
接下来redis通用类的编写:
package redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPubSub; public class RedisUtil { private static JedisPool jedisPool; private RedisUtil(){ } static { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxIdle(5); poolConfig.setMinIdle(1); poolConfig.setTestOnBorrow(true); poolConfig.setNumTestsPerEvictionRun(10); poolConfig.setTimeBetweenEvictionRunsMillis(60000); poolConfig.setMaxWaitMillis(10000); jedisPool = new JedisPool(poolConfig,"127.0.0.1",6379); } private static void returnResource(Jedis jedis) { jedisPool.returnResource(jedis); } /*发布消息*/ public static void publish(String channel, String message){ Jedis jedis = null ; try{ jedis = jedisPool.getResource(); jedis.publish(channel, message); }catch(Exception e){ System.out.println(e); }finally{ returnResource(jedis); } }; /*订阅房间*/ public static void subscribe(String[] room, JedisPubSub pubSub){ Jedis jedis = null ; try{ jedis = jedisPool.getResource(); jedis.subscribe(pubSub , room); }catch(Exception e){ System.out.println(e); }finally{ returnResource(jedis); } } }
最后是主函数启动客户端了:
public static void main(String[] args) throws InterruptedException { final Client client = new Client(); client.setName("Mark"); final String[] rooms = {"movie::live::room"}; new Thread(new Runnable() { @Override public void run() { // String[] rooms = {"peter::live::room","Bob::live::room"}; client.subscribe(rooms); } }).start(); Thread.sleep(3000); while(true){ System.out.print("say something:"); Scanner scanner = new Scanner(System.in); String message = scanner.nextLine(); if("quit".equals(message)){ break; }else{ client.say(rooms[0], message); System.out.println(); } } String[] unSubRoom ={"movie::live::room"}; client.unSubscribe(unSubRoom); }
到此,一个简单的聊天室编写完成。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- redis安装问题小结
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序