PageRenderTime 78ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/jyqp_netty/src/main/java/com/zk/netty/server/NettyServerHandler.java

https://bitbucket.org/shiyun3210/jyqp
Java | 287 lines | 233 code | 21 blank | 33 comment | 23 complexity | 2d4aa38dca71ee27c56b1661bc48db0d MD5 | raw file
  1. package com.zk.netty.server;
  2. import io.netty.channel.Channel;
  3. import io.netty.channel.ChannelHandler.Sharable;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import io.netty.channel.ChannelId;
  6. import io.netty.channel.DefaultChannelId;
  7. import io.netty.channel.SimpleChannelInboundHandler;
  8. import io.netty.channel.group.ChannelGroup;
  9. import io.netty.channel.group.DefaultChannelGroup;
  10. import io.netty.util.concurrent.GlobalEventExecutor;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.Iterator;
  14. import java.util.List;
  15. import java.util.Map;
  16. import java.util.Map.Entry;
  17. import java.util.Set;
  18. import org.apache.commons.collections.MapUtils;
  19. import org.apache.commons.lang.StringUtils;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22. import org.springframework.context.annotation.Scope;
  23. import org.springframework.stereotype.Service;
  24. import redis.clients.jedis.Tuple;
  25. import com.alibaba.fastjson.JSONObject;
  26. import com.alibaba.fastjson.TypeReference;
  27. import com.zk.netty.enums.GameRoom;
  28. import com.zk.netty.game.majiang.MajiangGame;
  29. import com.zk.netty.game.shuangjian.ShuangjianGame;
  30. import com.zk.netty.redis.RedisRoomService;
  31. import com.zk.netty.redis.RedisUserService;
  32. import com.zk.netty.user.service.UserService;
  33. import com.zk.netty.user.service.impl.UserServiceImpl;
  34. import com.zk.netty.util.DateTools;
  35. /**
  36. * 消息处理器
  37. * @author syf
  38. */
  39. @Service("nettyServerHandler")
  40. @Scope("prototype")
  41. @Sharable
  42. public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
  43. private Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);
  44. public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
  45. private UserService userService;
  46. public NettyServerHandler(){
  47. userService = new UserServiceImpl();
  48. }
  49. @Override
  50. public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
  51. logger.info(ctx.channel().remoteAddress() +"建立连接");
  52. channels.add(ctx.channel());
  53. }
  54. @Override
  55. public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
  56. logger.info(ctx.channel().remoteAddress() +"断开连接");
  57. channels.remove(ctx.channel());
  58. }
  59. @SuppressWarnings("unchecked")
  60. @Override
  61. public void channelRead(ChannelHandlerContext ctx, Object msg){
  62. Channel chnnel = ctx.channel();
  63. DefaultChannelId channelId = (DefaultChannelId)chnnel.id();
  64. logger.info("收到{},ID:{},消息:{}",chnnel.remoteAddress(),channelId,msg);
  65. logger.info("---------------验证消息-------------------");
  66. Map<String,Object> mapMsg = null;
  67. try {
  68. mapMsg = JSONObject.parseObject(msg.toString(), Map.class);
  69. if(MapUtils.isNotEmpty(mapMsg)){
  70. String uid = mapMsg.get("uid")==null?"":mapMsg.get("uid").toString();
  71. String token = mapMsg.get("token")==null?"":mapMsg.get("token").toString();
  72. if(StringUtils.isBlank(uid)||StringUtils.isBlank(token)){
  73. ctx.writeAndFlush("{\"code\":\"1\",\"msg\":\"token invalid\"}\n");
  74. return;
  75. }
  76. String value = RedisUserService.getToken(uid);
  77. if(StringUtils.isBlank(value)||!token.equals(value)){
  78. ctx.writeAndFlush("{\"code\":\"1\",\"msg\":\"token invalid\"}\n");
  79. return;
  80. }
  81. RedisUserService.setUserChannelId(uid, channelId);
  82. String msgType = mapMsg.get("msgtype")==null?"":mapMsg.get("msgtype").toString();
  83. String returnMsg = "";
  84. String data = mapMsg.get("data").toString();
  85. GameRoom gameRoom = GameRoom.getInstance(mapMsg.get("game_room_type").toString());
  86. String nowChannelId = channelId.asLongText();
  87. switch (msgType) {
  88. case "40001"://加入或更换房间
  89. if(gameRoom!=null){
  90. //检查用户是否已经在另外一个房间。
  91. String userInRoom = RedisUserService.getUserInRoom(uid);
  92. if(StringUtils.isNotBlank(userInRoom)){
  93. RedisUserService.clearUserByRoom(uid, userInRoom);
  94. sendRoomNewUserInfo(channelId.asLongText(), gameRoom, userInRoom);
  95. }
  96. //加入房间
  97. String roomId = joinRoom(uid, gameRoom,userInRoom);
  98. if(StringUtils.isNotBlank(roomId)){
  99. ctx.writeAndFlush(sendRoomNewUserInfo(nowChannelId,gameRoom, roomId));
  100. return;
  101. }
  102. }
  103. returnMsg = "{\"code\":\"-1\",\"msg\":\"加入房间失败\"}\n";
  104. break;
  105. case "40002"://离开房间
  106. if(gameRoom!=null){
  107. //检查用户是否已经在另外一个房间。
  108. String userInRoom = RedisUserService.getUserInRoom(uid);
  109. if(StringUtils.isNotBlank(userInRoom)){
  110. RedisUserService.clearUserByRoom(uid, userInRoom);
  111. sendRoomNewUserInfo(nowChannelId, gameRoom, userInRoom);
  112. }
  113. }
  114. returnMsg = "{\"code\":\"0\",\"msg\":\"ok\"}\n";
  115. break;
  116. case "40003"://准备
  117. String roomId = mapMsg.get("roomid").toString();
  118. int readyStatus = Integer.parseInt(mapMsg.get("ready_status").toString());
  119. int resultNum = RedisRoomService.setRoomReady(roomId, uid, readyStatus);
  120. if(gameRoom.getNumberPeople()==resultNum){
  121. if(gameRoom.getGameType()==1){
  122. String[] cards = ShuangjianGame.dealCard();
  123. sendCards(nowChannelId, gameRoom, roomId, cards);
  124. }else if(gameRoom.getGameType()==2){
  125. // String[] cards = MajiangGame.dealCard();
  126. // sendCards(nowChannelId, gameRoom, roomId, cards);
  127. }
  128. }else{
  129. sendRoomReadyStatus(nowChannelId, gameRoom, roomId);
  130. }
  131. returnMsg = "{\"code\":\"0\",\"msg\":\"ok\"}\n";
  132. break;
  133. case "40004":
  134. break;
  135. case "40005":
  136. break;
  137. case "40006":
  138. break;
  139. default:
  140. break;
  141. }
  142. ctx.writeAndFlush(returnMsg);
  143. }
  144. } catch (Exception e) {
  145. ctx.writeAndFlush("{\"code\":\"50010\",\"msg\":\"无法解析的JSON消息\"}\n");
  146. }
  147. }
  148. //{"code":"0","msg":"ok","uid":"46","token":"77ba3682e22f65b2080f4a6b4e006f26","msgtype":"40001","data":"sj1"}
  149. @Override
  150. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  151. ctx.writeAndFlush("{\"code\":\"0\",\"msg\":\"ok\"}\n");
  152. super.channelActive(ctx);
  153. }
  154. @Override
  155. protected void channelRead0(ChannelHandlerContext ctx, String msg)
  156. throws Exception {
  157. }
  158. /**
  159. * 加入房间
  160. * @param channelId
  161. * @param uid
  162. * @param mapMsg
  163. * @return
  164. */
  165. public String joinRoom(String uid,GameRoom gameRoom,String userInRoom){
  166. try {
  167. int uidInt = Integer.parseInt(uid);
  168. Map<String, Object> mapUser = userService.getUserShortInfoById(uidInt);
  169. if(MapUtils.isNotEmpty(mapUser)){
  170. mapUser.put("uid", uid);
  171. mapUser.put("joinroom_time", DateTools.getTime());
  172. mapUser.remove("id");
  173. if(gameRoom.getNumberPeople()==4){
  174. return RedisRoomService.joinFourRoom(gameRoom,uidInt,mapUser,userInRoom);
  175. }else{
  176. return RedisRoomService.joinThreeRoom(gameRoom,uidInt,mapUser,userInRoom);
  177. }
  178. }
  179. logger.info("{}用户不存在",uid);
  180. } catch (Exception e) {
  181. e.printStackTrace();
  182. }
  183. return null;
  184. }
  185. private static String sendRoomNewUserInfo(String nowChannelId,GameRoom gameRoom,String roomKey){
  186. Map<String,Object> mapRoom = new HashMap<String,Object>();
  187. mapRoom.put("roomid", roomKey);
  188. System.out.println("房间ID:"+roomKey);
  189. Set<Tuple> room = RedisRoomService.getRoomInfo(roomKey);
  190. List<String> listUser = new ArrayList<String>();
  191. List<ChannelId> listChannel = new ArrayList<ChannelId>();
  192. if(!room.isEmpty()){
  193. for(Tuple t : room){
  194. // Map<String,Object> roomUser = new HashMap<String,Object>();
  195. String userInfo = t.getElement();
  196. // Map<String,Object> mapUserInfo = JSONObject.parseObject(userInfo,new TypeReference<Map<String, Object>>(){});
  197. // System.out.println(mapUserInfo);
  198. // roomUser.put(((int)t.getScore())+"", mapUserInfo);
  199. listUser.add(userInfo);
  200. ChannelId channelId = RedisUserService.getUserChannelId(((int)t.getScore())+"");
  201. listChannel.add(channelId);
  202. }
  203. mapRoom.put("users", listUser);
  204. mapRoom.put("code", "0");
  205. mapRoom.put("msg", "ok");
  206. String returnMsg = JSONObject.toJSONString(mapRoom)+"\n";
  207. for(ChannelId channelId : listChannel){
  208. if(!nowChannelId.equals(channelId.asLongText())){
  209. System.out.println("发送给其他用户:"+channelId);
  210. channels.find(channelId).writeAndFlush(returnMsg);
  211. }
  212. }
  213. return returnMsg;
  214. }
  215. return "";
  216. }
  217. /**
  218. * 发送准备消息
  219. * @param nowChannelId
  220. * @param gameRoom
  221. * @param roomKey
  222. */
  223. private static void sendRoomReadyStatus(String nowChannelId,GameRoom gameRoom,String roomKey){
  224. Map<String,Object> mapRoom = new HashMap<String,Object>();
  225. mapRoom.put("roomid", roomKey);
  226. System.out.println("房间ID:"+roomKey);
  227. Map<String,String> room = RedisRoomService.getRoomReady(roomKey);
  228. if(!room.isEmpty()){
  229. mapRoom.put("users", room);
  230. mapRoom.put("code", "0");
  231. mapRoom.put("msg", "ok");
  232. String returnMsg = JSONObject.toJSONString(mapRoom)+"\n";
  233. for(String str : room.keySet()){
  234. ChannelId channelId = RedisUserService.getUserChannelId(str);
  235. if(!nowChannelId.equals(channelId.asLongText())){
  236. System.out.println("发送准备状态消息给其他用户:"+channelId);
  237. channels.find(channelId).writeAndFlush(returnMsg);
  238. }
  239. }
  240. }
  241. }
  242. /**
  243. * 发送准备消息
  244. * @param nowChannelId
  245. * @param gameRoom
  246. * @param roomKey
  247. */
  248. private static void sendCards(String nowChannelId,GameRoom gameRoom,String roomKey,String[] cards){
  249. Map<String,Object> mapRoom = new HashMap<String,Object>();
  250. mapRoom.put("roomid", roomKey);
  251. System.out.println("房间ID:"+roomKey);
  252. Map<String,String> room = RedisRoomService.getRoomReady(roomKey);
  253. if(!room.isEmpty()){
  254. mapRoom.put("code", "0");
  255. mapRoom.put("msg", "ok");
  256. int index = 0;
  257. for(Map.Entry<String, String> entry : room.entrySet()){
  258. ChannelId channelId = RedisUserService.getUserChannelId(entry.getKey());
  259. mapRoom.put("cards", cards[index]);
  260. String returnMsg = JSONObject.toJSONString(mapRoom)+"\n";
  261. System.out.println("发送牌给指定用户:"+channelId);
  262. channels.find(channelId).writeAndFlush(returnMsg);
  263. }
  264. }
  265. }
  266. }