客戶端邏輯
/**
* @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<String,String> user = new HashMap();//username:on/off_jinbi
public static List<String> user_group = new ArrayList();
public static List<ChannelHandlerContext> user_group_client = new ArrayList();
@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);
}
}