zoukankan      html  css  js  c++  java
  • 实现一个游戏服务器(1)引擎设计综述

    最近项目的开发工作较少,因此有时间能捣鼓自己的东西。于是花了大概两个星期的时间,粗略的搭起了一个游戏服务器的框架。

    对我而言重复造此轮子的意义有:

    (1)在经历过一个上线游戏项目的洗礼之后,作为对这一年的开发工作、技术学习的一个总结,将自己这一年来所学所得所思所想,通过代码表达出来。

    (2)作为一个对工作中不会接触到的一些新工具的使用的探索。项目组使用的技术已经是经过了时间的检验,并且趋于稳定。但是作为一个程序员,探索技术、保持学习能力乃是天职亦是乐趣。

    在我看来,在实现一个游戏服务器之前,有必要先对其架构做一个分析。规划好哪些工作交给引擎、哪些工作交给脚本实现。由于我目标是实现一个放置类的数值游戏(类似于战舰少女R),先可以粗略的认为没有很高的性能指标。于是,我可以大力简化我的服务器代码,在引擎里只做核心且必要的工作,其它的包括游戏玩法逻辑统统交给脚本层实现。保证引擎代码的精简、干净是十分有益的。

    总的来说,我认为有必要放在引擎里的功能有以下这些:

    (1)负责收发消息,解包封包的网络功能。

    (2)内嵌Python虚拟机的脚本功能。

    (3)开放给脚本层的一系列注册事件触发的功能。比如消息事件触发、逻辑事件触发、超时事件触发、定时事件触发等。

    其它的功能,包括连接管理、角色管理、战斗等功能全部由脚本实现。

    通过上述的简要分析,决定采用有常见的单进程多线程模型,服务器进程一共有3个线程,分别是:

    (1)网络线程(socket server)。使用libevent网络库实现,其工作是将从网络收到的消息包传递给逻辑线程、将逻辑线程投递来的写请求转换成网络消息包并发送出去。

    (2)逻辑线程(game server)。这部分包括了内嵌python虚拟机、消息事件触发模块(msg)、逻辑事件触发模块(event)、超时事件触发模块(timeout)、定时事件触发模块(datetime)。

    (3)日志线程(logger)。由于需要同步写日志、并且日志模块逻辑较为独立,因此单独独立出一个线程。

    线程之间通信也是一个需要考虑的问题。而我的做法是,所有线程之间的通信都是基于消息的传递的:网络线程收完一个完整的消息包之后要通知逻辑线程,则将网络消息包的内容打包投递到逻辑线程的消息队列里。逻辑线程、网络线程需要打log则投递一个请求到logger线程的消息队列。这里说是投递消息,其实实现上是投递一个指向消息的指针。对消息的内存的管理方式是使用人为的约定,定义好消息指针的所有权,而非使用智能指针。规定由消息的的产生方负责申请消息所使用的内存,并将其指针传递给处理方。消息处理方在处理完一条消息之后,有责任要负责回收这块消息的内存。

    逻辑线程请求发网络消息这个功能在实现上则稍有不同,不能做成简单的向消息队列投递消息。因为网络线程的事件循环是交给libevent控制的,因此不能实现成等待从队列里取消息。暂且做成读写一个本地互联的socket(类似于self pipe trick的变种),我称之为control socket。因此网络线程(socket server)管理两种不同的socket,分别是data socket和control socket。data socket是服务器与客户端连接的socket,control socket则是用于服务器内部线程通信的socket,负责传递逻辑线程对网络线程的请求,包括逻辑线程的请求发包、请求中断连接、请求主动连接等。

    以上便是这个游戏服务器引擎实现的大体描述。今后会继续写相关博客记录后续相关模块的开发过程、遇到的问题、踩过的坑等。先写下此文以示决心:)

    ============================================

    更新

    代码在这:https://github.com/adinosaur/game-server

  • 相关阅读:
    Windows下 如何添加开机启动项
    Android在 普通类(非Activity,多数为Adapter) 中 传输数据为空值 解决方法 :在startActivity 用 intent传输数据
    Android 从ImageView中获取Bitmap对象方法
    剑指offer(纪念版)读书笔记【实时更新】
    剑指offer(纪念版) 面试题3:二维数组中的查找
    C++ sizeof 误区 大公司面试题
    51 nod 1521 一维战舰 时间复杂度O(n),同 Codeforces 567D. One-Dimensional Battle Ships 有详细注释
    51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释
    51nod 1451 合法三角形 判斜率去重,时间复杂度O(n^2)
    关于JetBrains CLion 激活 (CLion License Activation)的解决办法,带hosts详细修改
  • 原文地址:https://www.cnblogs.com/adinosaur/p/7005424.html
Copyright © 2011-2022 走看看