导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客
从这一章开始,我们进入业务的部分,从注册登录开始。
创建注册和登录的路由
package com.loveprogrammer.command.server;
public interface ServerTag {
/***
* 注册
*/
int TAG_LOGIN_REGISTER = 1;
/***
* 登录
*/
int TAG_LOGIN_LOGIN = 2;
/***
* 测试
*/
int TAG_HELLO_HI = 99;
}
package com.loveprogrammer.command.server;
public interface ServerTopic {
/***
* 登录与测试
*/
int TOPIC_LOGIN = 1;
/***
* 问候
*/
int TOPIC_HELLO = 99;
}
handler的位置移到server中
编写登录的handler
LoginHandler.java
package com.loveprogrammer.handler;
import com.alibaba.fastjson2.JSON;
import com.loveprogrammer.base.network.command.BaseHandler;
import com.loveprogrammer.base.network.command.anotation.TagListener;
import com.loveprogrammer.base.network.command.anotation.TopicListener;
import com.loveprogrammer.command.server.ServerTag;
import com.loveprogrammer.command.server.ServerTopic;
import com.loveprogrammer.dto.login.UserRegister;
import com.loveprogrammer.domain.User;
import com.loveprogrammer.service.IUserService;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @ClassName LoginHandler
* @Description 登录
* @Author admin
* @Date 2024/2/6 15:49
* @Version 1.0
*/
@Component
@TopicListener(topic = ServerTopic.TOPIC_LOGIN)
public class LoginHandler extends BaseHandler {
public static final Logger log = LoggerFactory.getLogger(LoginHandler.class);
@Autowired
private IUserService userService;
@TagListener(tag = ServerTag.TAG_LOGIN_REGISTER,messageClass = UserRegister.class)
public void register(ChannelHandlerContext ctx, UserRegister register){
log.info("数据内容:data=" + JSON.toJSONString(register));
User user = userService.findUserByNickname(register.getName());
if(user == null) {
user = new User();
user.setNickName(register.getName());
user.setPassword("111111");
user.setAccount(register.getName());
userService.save(user);
}
else{
log.warn("用户已经存在");
}
//StringMessage message = StringMessage.create(0,0);
//message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);
//message.setBody(result);
//SessionManager.getInstance().sendMessage(ctx.channel(),message);
}
}
修改客户端
SocketClient.java
package com.loveprogrammer.netty.simple;
import com.loveprogrammer.codec.MessageDecoder;
import com.loveprogrammer.codec.MessageEncoder;
import com.loveprogrammer.command.server.ServerTag;
import com.loveprogrammer.command.server.ServerTopic;
import com.loveprogrammer.constants.ConstantValue;
import com.loveprogrammer.pojo.StringMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @ClassName SocketClient
* @Description TODO
* @Author admin
* @Date 2024/1/29 17:43
* @Version 1.0
*/
public class SocketClient {
private static final Logger logger = LoggerFactory.getLogger(SocketClient.class);
private static final String IP = "127.0.0.1";
private static final int PORT = 8088;
private static EventLoopGroup group = new NioEventLoopGroup();
protected static void run() throws InterruptedException {
// Bootstrap bootstrap = new Bootstrap();
// bootstrap.group(group);
// bootstrap.channel(NioSocketChannel.class);
// bootstrap.handler(new ChannelInitializer() {
// protected void initChannel(Channel ch) throws Exception {
// ChannelPipeline pipeline = ch.pipeline();
// pipeline.addLast("framer",new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
// pipeline.addLast("decoder",new StringDecoder());
// pipeline.addLast("encoder",new StringEncoder());
// pipeline.addLast(new SocketClientHandler());
// }
// });
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group);
bootstrap.channel(NioSocketChannel.class);
bootstrap.handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("encoder", new MessageEncoder());
pipeline.addLast("decoder", new MessageDecoder(ConstantValue.MESSAGE_CODEC_MAX_FRAME_LENGTH,
ConstantValue.MESSAGE_CODEC_LENGTH_FIELD_LENGTH, ConstantValue.MESSAGE_CODEC_LENGTH_FIELD_OFFSET,
ConstantValue.MESSAGE_CODEC_LENGTH_ADJUSTMENT, ConstantValue.MESSAGE_CODEC_INITIAL_BYTES_TO_STRIP,
false));
pipeline.addLast(new SocketClientHandler());
}
});
// 连接服务器
ChannelFuture channelFuture = bootstrap.connect(IP, PORT).sync();
StringMessage msg = StringMessage.create(ServerTopic.TOPIC_HELLO, ServerTag.TAG_HELLO_HI);
msg.setStatusCode(200);
msg.setBody("你好,我是eric");
// msg += "\r\n";
channelFuture.channel().writeAndFlush(msg);
logger.info("向服务器发送消息 {}",msg);
channelFuture.channel().closeFuture().sync();
}
public static void main(String[] args) throws InterruptedException {
logger.info("开始连接Socket服务器...");
try {
run();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
SocketClientHandler.java
package com.loveprogrammer.netty.simple;
import com.alibaba.fastjson2.JSON;
import com.loveprogrammer.command.server.ServerTag;
import com.loveprogrammer.command.server.ServerTopic;
import com.loveprogrammer.dto.login.UserRegister;
import com.loveprogrammer.pojo.StringMessage;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Scanner;
/**
* @ClassName SocketClientHandler
* @Description TODO
* @Author admin
* @Date 2024/1/29 17:41
* @Version 1.0
*/
public class SocketClientHandler extends SimpleChannelInboundHandler<StringMessage> {
private static final Logger logger = LoggerFactory.getLogger(SocketClientHandler.class);
@Override
public void exceptionCaught(ChannelHandlerContext arg0, Throwable arg1) {
logger.info("异常发生", arg1);
}
@Override
public void channelRead(ChannelHandlerContext arg0, Object msg) throws Exception {
super.channelRead(arg0, msg);
}
@Override
protected void channelRead0(ChannelHandlerContext context, StringMessage data) {
logger.info("数据内容:data=" + data);
// 注册一个用户
System.out.println("请输入注册的用户名");
Scanner input = new Scanner(System.in);
String name = input.nextLine();
UserRegister register = new UserRegister();
register.setName(name);
StringMessage msg = StringMessage.create(ServerTopic.TOPIC_LOGIN,ServerTag.TAG_LOGIN_REGISTER);
msg.setStatusCode(200);
msg.setBody(JSON.toJSONString(register));
context.channel().writeAndFlush(msg);
logger.info("向服务器发送注册用户消息 {}",msg);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.info("客户端连接建立");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
logger.info("客户端连接断开");
super.channelInactive(ctx);
}
}
运行测试
客户端填写用户名
09:37:29.895 [nioEventLoopGroup-2-1] [INFO ] com.loveprogrammer.netty.simple.SocketClientHandler:37 --- 数据内容:data=StringMessage{messageId=0, statusCode=1, length=76, body='我是服务器,我收到了你的信息:你好,我是eric,sessionId = 1'}
请输入注册的用户名
eric
09:46:33.692 [nioEventLoopGroup-2-1] [INFO ] com.loveprogrammer.netty.simple.SocketClientHandler:49 --- 向服务器发送注册用户消息 StringMessage{messageId=1, statusCode=200, length=0, body='{"name":"eric"}'}
服务端响应
2024-02-07 09:37:29.892 INFO 14596 --- [ worker-pool-0] com.loveprogrammer.handler.HelloHandler : 数据内容:data=你好,我是eric
2024-02-07 09:46:33.753 INFO 14596 --- [ worker-pool-0] com.loveprogrammer.handler.LoginHandler : 数据内容:data={"name":"eric"}
Hibernate: select user0_.id as id1_0_, user0_.account as account2_0_, user0_.email as email3_0_, user0_.nick_name as nick_nam4_0_, user0_.password as password5_0_ from tbl_user user0_ where user0_.nick_name=?
Hibernate: insert into tbl_user (account, email, nick_name, password) values (?, ?, ?, ?)
全部源码详见:
gitee : eternity-online: 多人在线mmo游戏 - Gitee.com
分支:step-07