客戶端unity3d已經把消息發送到netty服務器上了,那么ServerHandler類的public void channelRead(ChannelHandlerContext ctx, Object msg) 就會觸發,
所有我們在這里吧消息發送至各自處理的類,這里呢我根據不同的消息類型,定義了不同的消息分派類。如login消息就制定LoingDispatch類,專門處理登錄這個模塊。
public class LoginProtocol { /* * Login_Area * **/ public static final int Area_LoginRequest = 0; // 登陸請求 public static final int Area_LoginResponse = 1; //登錄應答 /* * Login_Command * **/ public static final int Login_InvalidMessage = 0;//無效消息 public static final int Login_InvalidUsername = 1;//無效用戶名 public static final int Login_InvalidPassword = 2;//密碼錯誤 public static final int Login_Succeed = 10;//登陸成功 }
public class LoginDispatch { private static LoginDispatch instance = new LoginDispatch(); public static LoginDispatch getInstance() { return instance; } public void dispatch(ChannelHandlerContext ctx, SocketModel message) { switch (message.getArea()) { case LoginProtocol.Area_LoginRequest: //處理登錄的事務 break; default: break; } } }
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception//當客戶端發送數據到服務器會觸發此函數 { SocketModel message = (SocketModel) msg; switch (message.getType()) { case TypeProtocol.TYPE_LOGIN: LoginDispatch.getInstance().dispatch(ctx, message);//分派登錄消息 break; case TypeProtocol.TYPE_WIZARD: WizardDispatch.getInstance().dispatch(ctx, message); break; case TypeProtocol.TYPE_USER: UserDispatch.getInstance().dispatch(ctx, message); break; case TypeProtocol.TYPE_BATTLE: BattleDispatch.getInstance().dispatch(ctx, message); default: break; }
接着我們處理登錄事務搞出點事情,你也可以嘗試這打印幾句話,看客戶端和服務端能否正常的通信,如果可以請看下面:
測試好了之后,我們要把客戶端發送過來的消息,其中捎帶的賬號和密碼給解析出來,然后放到數據庫中驗證,再把是否成功類型賦給SocketModel的Command,返發送給客戶端。
這樣客戶端就根據command的值做不同的處理。
當然這只是我個人的觀點,有問題可以和我談談。
這個你們應該可以自己寫了吧,無非就是一些邏輯的判斷,通過這句ctx.writeAndFlush(消息(SocketModel));發送給客戶端。
public class LoginDispatch { private static LoginDispatch instance = new LoginDispatch(); public static LoginDispatch getInstance() { return instance; } public User user = null; public Wizard wizard = null; public void dispatch(ChannelHandlerContext ctx, SocketModel message) { switch (message.getArea()) { case LoginProtocol.Area_LoginRequest: LoginResponse(ctx,message); break; default: break; } } /* * **檢測用戶登錄是否密碼錯誤,用戶名不存在等,返回int對應的不同類型 */ public int LoginCheck(ChannelHandlerContext ctx,SocketModel request) { List<String> message = request.getMessage(); String username = message.get(0); String password = message.get(1); //System.out.println(username); //System.out.println(password); if (message.isEmpty()) { return LoginProtocol.Login_InvalidMessage; }else{ if (UserMySQL.getInstance().usernameExit(username)) { user = UserMySQL.getInstance().userExit(username, password,ctx.channel()); if (user != null){ return LoginProtocol.Login_Succeed; }else{ return LoginProtocol.Login_InvalidPassword; } }else{ return LoginProtocol.Login_InvalidUsername; } } } public void LoginResponse(ChannelHandlerContext ctx,SocketModel request) { SocketModel response = new SocketModel(); int command = LoginCheck(ctx, request); response.setType(TypeProtocol.TYPE_LOGIN); response.setArea(LoginProtocol.Area_LoginResponse); response.setCommand(command); response.setMessage(request.getMessage()); ctx.writeAndFlush(response); if (command == LoginProtocol.Login_Succeed) { LoginUser(ctx,request);//如果成功就登陸用戶,並開始新手向導 } } /** * 登陸用戶,並開始新手向導 * @param ctx */ public void LoginUser(ChannelHandlerContext ctx,SocketModel socketModel) { user = UserMySQL.getInstance().initUser(User.getUserByChannel(ctx.channel())); user.setWizard(WizardMySQL.getInstance().initWizard(user.getUserID())); SocketModel message = new SocketModel(); message.setType(TypeProtocol.TYPE_WIZARD); message.setArea(WizardProtocol.Wizard_Create_Request); message.setCommand(user.getWizard().getStepIndex()); message.setMessage(null); ctx.writeAndFlush(message); } }
這里是我寫的分派類,思路大概就是這樣。注意我這是有數據庫的,需要去數據庫里面驗證正確性。你們可以自己寫,因為每個人都不同。
我推薦用phpamdin來管理mysql數據庫,簡單方便。
里面存有4個賬號
好了運行試試,我隨便輸一個賬號,
可以看到服務器收到了客戶端發送的賬戶密碼,
我們在看看客戶端,由於我寫了登陸成功的話就跳轉場景,並在console中可以看到“登陸成功”的debug