[SpringDataMongodb开发游戏服务器实战]

背景:

        xdb其实足够完美了,现在回想一下,觉得有点复杂,我们不应该绑定语言,最好有自己的架构思路。

        七号堡垒作为成功的商业项目,告诉我:其实数据是多读少写的,有修改的时候直接改库也是没问题的,这样子有个好处就是rpc获取到的数据足够的准确。

        跨服这块结合redis,我们可以轻松获取其它服的数据。

        华珺的Player数据管理思路,将所有的数据都存放Role上,这样子获取是十分的简单。

        因此,我决定写一个简单而又足够上线的框架,思路:

                技术栈:  SpringBoot+netty+mongo+pb 。

                是按照模块划分成多线程的,也就是: 尽量单进程多线程去完成任务。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.jn</groupId><artifactId>mongodemo</artifactId><version>1.0</version><name>mongodemo</name><description>Demo project for Spring Boot</description><properties><java.version>21</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

MongoConfig.java

package com.jn.framework.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;@Configuration
public class MongoConfig {@SuppressWarnings("all")@Beanpublic MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDatabaseFactory, MongoMappingContext mongoMappingContext) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory);MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);//去掉_class字段mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return new MongoTemplate(mongoDatabaseFactory, mappingConverter);}
}

SpringBeanUtil.java

package com.jn.framework.utils;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** 普通的Java类中获取spring中的bean通用类*/
@Component
public class SpringBeanUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if (SpringBeanUtil.applicationContext == null) {SpringBeanUtil.applicationContext = applicationContext;}}//通过class获取Bean.public static <T> T getBean(Class<T> clazz) {return applicationContext.getBean(clazz);}}

AbsEntity.java

package com.jn.framework;import com.jn.framework.utils.SpringBeanUtil;
import org.springframework.data.repository.CrudRepository;import java.lang.reflect.ParameterizedType;/*** @param <T> 泛型参数用于保存Entity*/
@SuppressWarnings("all")
public abstract class AbsEntity<T extends CrudRepository> {public final void save() {ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();// 获取泛型参数类型,这里只有一个参数,因此取位置是0Class<? extends CrudRepository> repositoryType = (Class<T>) parameterizedType.getActualTypeArguments()[0];SpringBeanUtil.getBean(repositoryType).save(this);}
}

IProcedure.java

package com.jn.framework;public interface IProcedure {void call();
}

PlayerEntity.java

package com.jn.mongodemo.account.entity;import com.jn.framework.AbsEntity;import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;@Data
@Document("PlayerEntity")
public class PlayerEntity extends AbsEntity<PlayerEntityRepository> {@Id@Indexedprivate Long roleId;
}

PlayerEntityRepository.java

package com.jn.mongodemo.account.entity;import org.springframework.data.mongodb.repository.MongoRepository;public interface PlayerEntityRepository extends MongoRepository<PlayerEntity, Long> {}

PLogin.java

package com.jn.mongodemo.account.procedure;import com.jn.framework.IProcedure;
import com.jn.framework.utils.SpringBeanUtil;
import com.jn.mongodemo.account.entity.PlayerEntity;
import com.jn.mongodemo.account.entity.PlayerEntityRepository;
import com.jn.mongodemo.bag.entity.BagEntity;
import com.jn.mongodemo.bag.entity.BagEntityRepository;
import com.jn.mongodemo.role.Role;public class PLogin implements IProcedure {private long roleId;public PLogin(long roleId) {this.roleId = roleId;}@Overridepublic void call() {// 加载玩家信息PlayerEntityRepository playerEntityRepository = SpringBeanUtil.getBean(PlayerEntityRepository.class);PlayerEntity playerEntity = playerEntityRepository.findById(roleId).orElse(null);if (playerEntity == null) {playerEntity = new PlayerEntity();playerEntity.setRoleId(roleId);playerEntityRepository.save(playerEntity);}Role.inst().setPlayerEntity(playerEntity);// 背包信息BagEntityRepository bagEntityRepository = SpringBeanUtil.getBean(BagEntityRepository.class);BagEntity bagEntity = bagEntityRepository.findById(roleId).orElse(null);if (bagEntity == null) {bagEntity = new BagEntity();bagEntity.setRoleId(roleId);bagEntity.setNum(100);bagEntityRepository.save(bagEntity);}Role.inst().setBagEntity(bagEntity);// 测试修改Role.inst().getBagEntity().setNum(Role.inst().getBagEntity().getNum() + 100);Integer num = Role.inst().getBagEntity().getItemMap().getOrDefault(1, 0);Role.inst().getBagEntity().getItemMap().put(1, num+1);Role.inst().getBagEntity().save();}
}

AccountMsgHandler.java

package com.jn.mongodemo.account;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jn.mongodemo.account.procedure.PLogin;@RestController
@RequestMapping("/account")
public class AccountMsgHandler {/*http://localhost:8080/account/login?roleId=3*/@RequestMapping("/login")public void login(Long roleId) {new PLogin(roleId).call();}
}

BagEntity.java

package com.jn.mongodemo.bag.entity;import com.jn.framework.AbsEntity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.HashMap;
import java.util.Map;@Data
@Document("BagEntity")
public class BagEntity extends AbsEntity<BagEntityRepository> {@Id@Indexedprivate Long roleId;private Integer num;private Map<Integer, Integer> itemMap = new HashMap<>();
}

BagEntityRepository.java

package com.jn.mongodemo.bag.entity;import org.springframework.data.mongodb.repository.MongoRepository;public interface BagEntityRepository extends MongoRepository<BagEntity, Long> {}

Role.java

package com.jn.mongodemo.role;import com.jn.mongodemo.account.entity.PlayerEntity;
import com.jn.mongodemo.bag.entity.BagEntity;
import lombok.Data;@Data
public class Role {private static Role instance = new Role();public static Role inst() {return instance;}private PlayerEntity playerEntity;private BagEntity bagEntity;
}

MongodemoApplication.java

package com.jn;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MongodemoApplication {public static void main(String[] args) {SpringApplication.run(MongodemoApplication.class, args);}}

application.yml

spring:data:mongodb:host: 127.0.0.1port: 27017database: mongodemo

效果:

总结:

可见游戏服使用mongo是十分合适的,轻松面对复杂的数据结构,并且和java集合框架完美结合。 

其实,修改数据这块,我们可以登录时是: 同步记载,保存时,可以异步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2807833.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

推荐一个 Obsidian 的 ChatGPT 插件

源码地址&#xff1a;https://github.com/nhaouari/obsidian-textgenerator-plugin Text Generator 是目前我使用过的最好的 Obsidian 中的 ChatGPT 功能插件。它旨在智能生成内容&#xff0c;以便轻松记笔记。它不仅可以在 Obsidian 中直接使用 ChatGPT&#xff0c;还提供了优…

Python staticmethod函数

Python是一种功能强大且灵活的编程语言&#xff0c;具有许多特性和功能&#xff0c;其中之一就是staticmethod函数。staticmethod函数是Python中用于定义静态方法的一种特殊装饰器。在本文中&#xff0c;将深入探讨staticmethod函数的用法、优势以及与其他方法类型的比较。 什…

【力扣 - 将有序数组转化为二叉搜索树】

题目描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 题解 前言 二叉搜索树的中序遍历是升序序列&a…

黑马JavaWeb开发跟学(一)Web前端开发HTML、CSS基础

黑马JavaWeb开发一.Web前端开发HTML、CSS基础 引子、Web开发介绍传统路线本课程全新路线本课程适用人群课程收获一、什么是web开发二、网站的工作流程三、网站的开发模式四、网站的开发技术 前端开发基础一、前端开发二、HTML & CSS2.1 HTML快速入门2.1.1 操作第一步第二步…

Arduino中安装ESP32网络抽风无法下载 暴力解决办法 python

不知道什么仙人设计的arduino连接网络部分&#xff0c;死活下不下来。&#xff08;真的沙口&#xff0c;第一次看到这么抽风的下载口&#xff09; 操作 给爷惹火了我踏马解析json选zip直接全部下下来 把这个大家的开发板管理地址下下来跟后面python放在同一目录下&#xff0c…

FDTD算法总结

计算电磁学(Computational Electromagnetics, CEM)是通过数值计算来研究电磁场的交叉学科。 数值求解电磁学问题的方法可以分成频域(Frequency Doamin, FD)、时域(Time Domain, TD)等两类。 频域法基于时谐微分&#xff0c;通过对多个采样值的傅里叶逆变换得到所需的脉冲响应…

构建高效教学平台系统:关键要素与最佳实践

随着在线教育的迅速发展&#xff0c;教学平台系统成为了教育行业不可或缺的一部分。本文将总结构建高效教学平台系统的关键要素&#xff0c;并介绍最佳实践&#xff0c;以帮助教育机构和企业打造具有竞争力的教学平台系统。 引言&#xff1a; 随着信息技术的不断进步和普及&…

神经网络系列---分类度量

文章目录 分类度量混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff1a;二分类问题二分类代码多分类问题多分类宏平均法:多分类代码多分类微平均法&#xff1a; 准确率&#xff08;Accuracy&#xff09;&#xff1a;精确率&#xff08;Precision&#xff09;&#xf…

K8s安全一

Kubernetes是一个开源的&#xff0c;用于编排云平台中多个主机上的容器化的应用&#xff0c;目标是让部署容器化的应用能简单并且高效的使用, 提供了应用部署&#xff0c;规划&#xff0c;更新&#xff0c;维护的一种机制。其核心的特点就是能够自主的管理容器来保证云平台中的…

值得推荐收藏的5款顶级免费数据恢复软件!

今天分享5个超级简单又适合电脑小白的恢复删除的文件的恢复方法&#xff01; 在我们的日常生活中&#xff0c;偶尔会因为误删除或者清空回收站等原因导致数据丢失。对于电脑小白来说&#xff0c;这或许是一个非常棘手的问题。但是&#xff0c;不用太担心&#xff0c;今天我为大…

【C++那些事儿】C++入门 | 命名空间 | 缺省参数 | 引用 | 内联函数 | auto关键字 | 范围for循环 | nullptr

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C那些事儿 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 前言1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4. 缺…

模型上下文长度达到10000000,又一批创业者完蛋了?

没有疑问&#xff0c;Gemini 1.5 Pro的隆重推出被Sora抢了风头。 社交平台X上OpenAI介绍Sora的第一条动态&#xff0c;现在已经被浏览了超过9000万次&#xff0c;而关于Gemini 1.5 Pro热度最高的一条&#xff0c;来自谷歌首席科学家Jeff Dean&#xff0c;区区123万人。 或许J…

【设计模式】策略模式及函数式编程的替代

本文介绍策略模式以及使用函数式编程替代简单的策略模式。 策略模式 在策略模式&#xff08;Strategy Pattern&#xff09;中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式定义了一系列算法或策略&#xff0c;并将每个算法封装在独立…

Jenkins解决Host key verification failed (2)

Jenkins解决Host key verification failed 分析原因情况 一、用OpenSSH的人都知ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时&#xff0c;OpenSSH会核对公钥。如果公钥不同&#xff0c;OpenSSH会发出警告&#xff0c;避免…

基于SpringBoot的航班进出港管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

【Java程序设计】【C00319】基于Springboot的志愿服务管理系统(有论文)

基于Springboot的志愿服务管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的志愿服务管理系统设计与实现&#xff0c;本系统有管理员以及用户二种角色权限 管理员&#xff1a;首页、个人中心、管理员管理、…

【MATLAB源码-第146期】基于matlab的信源编码仿真GUI,对比霍夫曼编码,算术编码和LZ编码。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 霍夫曼编码、算术编码和LZ编码是三种广泛应用于数据压缩领域的编码技术。它们各自拥有独特的设计哲学、实现方式和适用场景&#xff0c;因此在压缩效率、编解码速度和内存使用等方面表现出不同的特点。接下来详细描述这三种编…

Base64 编码 lua

Base64 编码 -- Base64 字符表 local base64_chars { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,…

freeswitch 权威指南 --- 高级篇

官网文档&#xff1a;https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/ 关于 freeswitch 的公开教程&#xff1a;https://zhuanlan.zhihu.com/p/451981734 内容来自 《FreeSWITCH 权威指南》&#xff1a;目录&#xff1a;https://juejin.cn/post/702058079…

Vue+SpringBoot打造开放实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…