客户端逻辑
/**
* @Description:
* @version: v1.0.0
* @author: wbl
* @date: 2020年1月13日 下午1:22:29
*/
public class ClientHandler extends ChannelInboundHandlerAdapter{
public static String Name = "";
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
}
/**
* @Description:
*
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(null == msg) return;
String data = (String) msg;//收到数据
if("牛牛客户端登录成功!".equals(data)){
System.out.println("牛牛客户端启动成功!");
System.out.println("请选择序号:1.登录 2.注册");
String cli = read();
if("1".equals(cli)){
System.out.println("请输入用户名:");
Name = read();
ctx.channel().writeAndFlush("wbl1"+Name);
}else if("2".equals(cli)){
System.out.println("请输入新用户名:");
Name = read();
ctx.channel().writeAndFlush("wbl2"+Name);
}else{
System.out.println("指令输入有误,请重新输入:1.登录 2.注册");
Name = read();
ctx.channel().writeAndFlush("wbl2"+Name);
}
}else if(data.contains("wbl2")||data.contains("wbl3")){
System.out.println(data.substring(4));
System.out.println("请选择序号:1.登录 2.注册");
while(true){
String cli = read();
if("1".equals(cli)){
System.out.println("请输入用户名:");
Name = read();
ctx.channel().writeAndFlush("wbl1"+Name);
break;
}else if("2".equals(cli)){
System.out.println("请输入新用户名:");
Name = read();
ctx.channel().writeAndFlush("wbl2"+Name);
break;
}else{
System.out.println("指令输入有误,请重新输入:1.登录 2.注册");
}
}
}else if(data.contains("wbl1")||data.contains("wbl4")){
System.out.println(data.substring(4));
System.out.println("百人牛牛游戏开始!请输入命令序号:1随机抢庄入桌(匹配) 2.查询账户信息 3.退出");
while(true){
String cli = read();
if("1".equals(cli)){
ctx.channel().writeAndFlush("wbl3"+Name);
break;
}else if("2".equals(cli)){
ctx.channel().writeAndFlush("wbl4"+Name);
break;
}else if("3".equals(cli)){
ctx.channel().writeAndFlush("wbl5"+Name);
System.out.println("客户端正常登出,"+Name+"账号非常安全!");
System.exit(1);
}else{
System.out.println("指令输入有误,请重新输入:1随机抢庄入桌(匹配) 2.查询账户信息 3.退出");
}
}
}else if(data.contains("wbl5") || data.contains("wbl6")){//开始返回结果
System.out.println(data.substring(4));
while(true){
System.out.println("\n\n百人牛牛游戏开始!请输入命令序号:1随机抢庄入桌(匹配) 2.查询账户信息 3.退出");
String cli = read();
if("1".equals(cli)){
ctx.channel().writeAndFlush("wbl3"+Name);
break;
}else if("2".equals(cli)){
ctx.channel().writeAndFlush("wbl4"+Name);
break;
}else if("3".equals(cli)){
System.out.println("客户端正常登出,"+Name+"账号非常安全!");
ctx.channel().writeAndFlush("wbl5"+Name);
System.exit(1);
}else{
System.out.println("指令输入有误,请重新输入:1随机抢庄入桌(匹配) 2.查询账户信息 3.退出");
}
}
}
}
/**
* @Description:
*
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("客户端异常关闭,游戏结束!");
try{
ctx.channel().writeAndFlush("wblquit"+Name);
}catch(Exception e){
System.out.println("客户端中断,未通知到服务端,将延时5分钟,客户端在服务器自动登出");
}
ctx.close();
}
/** 空闲次数 */
private int idle_count = 1;
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
if (obj instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) obj;
if (IdleState.WRITER_IDLE.equals(event.state())) { // 如果写通道处于空闲状态就发送心跳命令
String str = "xintiao";
ctx.channel().writeAndFlush(str);
}
}
}
public static String read() throws Exception{
String str = "";
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
str = sc.next();
break;
}
return str;
}
}
服务端逻辑
/**
* @Description:
* @version: v1.0.0
* @author: wbl
* @date: 2020年1月13日 下午1:22:29
*/
public class DivServerHandler extends ChannelInboundHandlerAdapter{
public static Map
public static List
public static List
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("有新的客户端登录:"+ ctx.channel().remoteAddress().toString());
DivChannelInitializer.client_active ++;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {//ctx.close();//close会自动调用本方法
DivChannelInitializer.client_active --;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String)msg;
if("logon".equals(body)){
ctx.channel().writeAndFlush("牛牛客户端登录成功!");
return;
}else if(body.contains("wbl1")){//登录
String name = body.substring(4);
if(user.containsKey(name)){
user.put(name, "1_"+yue(name));
ctx.channel().writeAndFlush("wbl1牛气冲天的用户-"+name +"-登录成功!"
+" 账号余额:"+yue(name)
+" 当前在线人数:"+currentOnLine());
return;
}else{
ctx.channel().writeAndFlush("wbl2"+body.substring(4) +"-用户未注册!");
return ;
}
}else if(body.contains("wbl2")){//注册
String name = body.substring(4);
if(user.containsKey(name)){
ctx.channel().writeAndFlush("wbl3"+body.substring(4) +"-用户已注册,请换个其他名字!");
return;
}else{
user.put(body.substring(4), "1_20");
ctx.channel().writeAndFlush("wbl4牛气冲天的用户-"+body.substring(4) +"-注册并登录成功!");
return;
}
}else if(body.contains("wbl3")){//开始
String name = body.substring(4);
user_group.add(name);
user_group_client.add(ctx);
int num = currentOnLine();
if(user_group_client.size() >=2){
String resu = NiuInit.init();
System.out.println("发布游戏结果:"+resu);
for(int j = 0;j < user_group_client.size();j++){
ChannelHandlerContext gr = user_group_client.get(j);
gr.channel().writeAndFlush("wbl5" + resu);
}
user_group_client.clear();
user_group.clear();
Thread.sleep(5000);
}
}else if(body.contains("wbl4")){//查询
String name = body.substring(4);
String kvalue = user.get(name);
kvalue = kvalue.substring(2);
ctx.channel().writeAndFlush("wbl6 牛牛用户"+name +"当前帐号余额为:" + kvalue);
}else if(body.contains("wbl5")){//退出
String name = body.substring(4);
String kvalue = user.get(name);
user.put(name,"0_"+kvalue.substring(2));
}
}
/**
* 超时处理,如果HEARTBEAT_TIME秒没有收到客户端的心跳,就触发;
*/
/** 空闲次数 */
private int idle_count = 1;
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
if (obj instanceof IdleStateEvent) {
System.out.println("服务端收到xintiao....");
IdleStateEvent event = (IdleStateEvent) obj;
if (IdleState.READER_IDLE.equals(event.state())) {
if (idle_count > 2) {
System.out.println("超过两次无客户端请求,关闭该channel");
ctx.channel().close();
}
System.out.println("已等待"+DivChannelInitializer.HEARTBEATTIME
+DivChannelInitializer.TIME_UNIT
+"还没收到客户端发来的消息");
idle_count++;
}
} else {
super.userEventTriggered(ctx, obj);
}
}
/**
* 当发生异常时,打印异常 日志,释放客户端资源
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
/**释放资源*/
System.out.println("退出游戏!");
ctx.close();
}
//获取当前在线人数
public int currentOnLine(){
int len = 0;
for(String value : user.values()){
if(value.contains("1_")){
len ++;
}
}
return len;
}
//获取当前用户的金币数
public static String yue(String name){
String value = user.get(name);
String jb = value.substring(2);
return jb;
}
//写入金币数
public static void write(String name,int mon){
user.put(name, "1_"+mon);
}
}