Netty游戲服務器之六服務端登錄消息處理


客戶端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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM