Netty游戏服务器之六服务端登录消息处理

摘要:
//登录应答/**Login_命令***/publicstaticfinalintLogin_InvalidMessage=0;//无效的用户名publicstaticfinalintLogin_InvalidPassword=2;//处理登录事务中断;

客户端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数据库,简单方便。

Netty游戏服务器之六服务端登录消息处理第1张

里面存有4个账号

好了运行试试,我随便输一个账号,Netty游戏服务器之六服务端登录消息处理第2张

可以看到服务器收到了客户端发送的账户密码,Netty游戏服务器之六服务端登录消息处理第3张

我们在看看客户端,由于我写了登陆成功的话就跳转场景,并在console中可以看到“登陆成功”的debug

Netty游戏服务器之六服务端登录消息处理第4张

免责声明:文章转载自《Netty游戏服务器之六服务端登录消息处理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WinForm中DataGridView的使用(五)SQL基本语法总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Ansible 拷贝文件或目录

写法如下: [root@localhost ~]$ ansible 192.168.119.134 -m copy -a "src=/etc/passwd dest=/tmp/passwd owner=root group=root mode=0644" # 拷贝本机文件到远程客户端 [root@localhost ~]$ ansible 192....

ios 网络开发(CFNetwork)

CFNetwork 存在于CoreFoundation中的一个低级别但高性能的网络框架。BSD套接字的扩展,CFNetwork物理上和理论上都基于BSD套接字。有大量的Cocoa框架依赖于CFNetwork。 CFNetwork更侧重与网络协议,Foundation则更倾向于API数据请求等,虽然框架也提供了一些操作,但是远不如CFNetwork丰富。在学...

FTP协议的粗浅学习--利用wireshark抓包分析相关tcp连接

FTP相关文章: Linux上的ftp服务器 vsftpd 之配置满天飞--设置匿名用户访问(不弹出用户名密码框)以及其他用户可正常上传 ftp服务器Serv-U 设置允许自动创建不存在的目录     一、为什么写这个 昨天遇到个ftp相关的问题,关于ftp匿名访问的。花费了大量的脑细胞后,终于搞定了服务端的配置,现在客户端可以像下图一样,直接在浏览器输...

Redis的发布订阅

Redis的发布订阅 序言 发布订阅在设计模式中也可以说是观察者模式,针对这个模式是处理对象间一对多的依赖关系的,当一个对象发生变化,其它依赖他的对象都要得到通知并更新。 然而它也有自己的缺点,就是当主题发生一系列的变化时,观察者都要做批量的更新,如果这样的更新成本很高,那么解决方法就是根据种类需求通知,而不能盲目的通知所有的观察者。 那针对这个缺点,一般...

ES入门 (3) 语法(1)DDL(1) 索引操作

1 RESTful   REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可...

xxxx(四):接受消息hook地址分析

   今天来分析一下xxxx接受消息的call;测试的账号在虚拟机,发消息的账号在物理机;    1、老规矩:逆向分析的起点都从CE开始;给测试账号发送辨识度高的消息,这时暂时不要在测试账号打开消息。因为此时的消息刚经过网络传输,还是ASCII格式,所以千万不要勾选UTF-16,只能找ASCII码找(下面详细解释原因)!  重复发送0000000000、...