posts - 18,  comments - 21,  trackbacks - 0
上一篇 说了问题。现在说说重构后的构架。
基于freebsd6.3 boost-1.35.0(多处升级,最重要是包含了asio,升级了thread) STLport-5.1.5 消息队列(msgget,msgsnd,msgrcv)

构架方便借鉴了部分云风的思路。
loginserver,gate,gamedb,postoffice,mapserver
accountdb去掉了,整合进loginserver里,loginserver直接连oracle,取列表信息后去连gate,gate连gamedb负责发人物列表

家里机器只有画图。。。忍着看吧。。。
下面开始都是一个服为一个单位。
一个服的gate是可以随时开关的,gate起来的时候会给loginserver和postoffice注册
 1 struct GateInfo
 2 {
 3     char name[25];
 4     char ip[16];
 5     short port;
 6     uint online;
 7 };
 8 
 9 typedef vector<GateInfo*> VecGateInfo;
10 VecGateInfo _gateinfo;
11 
12 // 当有用户连上或者断开gate时
13 sort(_gateinfo.begin(), _gateinfo.end(), GateSort)
14 
15 // 这样client取gate信息的时候只需要发给每个gate_group的第一个就行。

gamedb是所有userinfo的集结地,有缓存,只在第一次请求的时候把userinfo读进缓存,其余时刻都是写,一个慢线程,5分钟轮询写一遍,某个user更新发给gamedb,由gamedb负责通知其他拷贝同步更新。

mapserver实际上是一堆服务端的组合总称,这块来自云风的构架,分为chatserver(聊天服务端),mapserver(地图服务端,还可以区分为只带功能性npc地图,或者称为非pk地图,和其他地图),guildserver,dropserver。。。每个server都和postoffice连接,并且按功能和gamedb和其他服务端连接,按功能划分具体的服务端可以很好的把逻辑分散,不会导致某个模块的bug整个服务端的崩溃,在程序员整体调试水平不高的情况下,大大降低出错后分析的难度。

相比较以前来说就是gamedb后移,数据重心放在gamedb上,只读一次的做法要严格保证gamedb的效率和稳定,否则会死的很抽象。

一些细节mark下来,boost+asio在freebsd上居然不用kqueue用的是select。。。Orz,这是我在一次单步跟一个内存错误发现的
 1 //
 2 // kqueue_reactor_fwd.hpp
 3 // ~~~~~~~~~~~~~~~~~~~~~~
 4 //
 5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 6 // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
 7 //
 8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 
12 #ifndef BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
13 #define BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
14 
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 
19 #include <boost/asio/detail/push_options.hpp>
20 
21 #if !defined(BOOST_ASIO_DISABLE_KQUEUE)
22 #if defined(__MACH__) && defined(__APPLE__)
23 
24 // Define this to indicate that epoll is supported on the target platform.
25 #define BOOST_ASIO_HAS_KQUEUE 1
26 
27 namespace boost {
28 namespace asio {
29 namespace detail {
30 
31 template <bool Own_Thread>
32 class kqueue_reactor;
33 
34 // namespace detail
35 // namespace asio
36 // namespace boost
37 
38 #endif // defined(__MACH__) && defined(__APPLE__)
39 #endif // !defined(BOOST_ASIO_DISABLE_KQUEUE)
40 
41 #include <boost/asio/detail/pop_options.hpp>
42 
43 #endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP
反正我只是不负责任的把22和38行屏蔽掉而已。

消息队列只传递指针,意思就是某个消息由接收方alloc,然后msgsnd这块内存的指针,msgrcv收到这个指针,处理完了free掉,而不是整个消息放进去。
1 struct mymsg {
2     long int    mtype;       /* message type */
3     char        mtext[4];    /* message text */
4 }
5 
说实话当初在msgsnd msgrcv上调试了很久
1 char* packet;// 假设这个packet包括了传进来的包
2 mymsg* msg = (mymsg*)mem_alloc(sizeof(mymsg));
3 memcpy(msg->mtext, &packet, sizeof(char*));
4 msgsnd(msgid, msg, sizeof(char*),0)
然后死活提示参数不正确。。。

逐字逐句读了man msgsnd数十遍之后发现。。。问题在msg->mtype不能等于0

ok,公司物理断网,usb口物理破坏。。。囧。。。当然,我要起带头作用,忍。。。
posted on 2008-04-09 22:42 大日如来 阅读(2328) 评论(2)  编辑 收藏 引用 所属分类: 游戏-编程

FeedBack:
# re: 搬服务端的体会--接着来。[未登录]
2008-04-10 09:33 | cppexplore
既然是传递指针进消息队列,取端进行free,想必是同一进程间的通讯吧。
为什么要用ipc的消息队列呢,很笨重,自己写线程消息队列性能更高,简直不是一个数量级的。  回复  更多评论
  
# re: 搬服务端的体会--接着来。[未登录]
2008-04-10 09:35 | cppexplore
附一个我实现的线程消息队列:http://www.cppblog.com/CppExplore/archive/2008/03/20/44949.html
消息类型的申请释放配合小对象内存池,完美的解决方案  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

留言簿(3)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜