43. 编程Part 3: 程序运行参数¶
iFun Engine中程序的设置内容通过 MANIFEST.json
进行管理。
因此,传输运行参数的方法大体上有在MANIFEST.json中指定参数的方法,以及添加命令行参数的方法。
43.1. 方法1: 利用MANIFEST.json¶
43.1.1. 在MANIFEST.json中添加参数¶
如下所示,在MANIFEST.json中添加名为 arguments
的JSON property,定义其中使用的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | {
"version": 1,
"components": [
{
"name": "MyProjectServer",
"arguments": {
"example_arg1": "val1",
"example_arg2": 100
},
"library": "libmy_project.so",
"dependency": {
...
"SessionService": {
"tcp_json_port": 8012,
...
},
...
}
}
]
}
|
43.1.2. 从服务器代码读取参数¶
已添加到MANIFEST.json中的参数将在相应服务器的Install函数被调用时传输。下面是读取上述MANIFEST.json的情况。
my_project_server.cc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class MyProjectServer : public Component {
public:
static bool Install(const ArgumentMap &arguments) {
LOG(INFO) << "Built using Engine version: " << FUNAPI_BUILD_IDENTIFIER;
// Kickstarts the Engine's ORM.
// Do not touch this, unless you fully understand what you are doing.
my_project::ObjectModelInit();
/*
* Parameters specified in the "arguments" section in your MANIFEST.json
* will be passed in the variable "arguments".
* So, you can give configuration data to your game server.
*
* Example:
*
* We have in MANIFEST.json "example_arg1" and "example_arg2" that
* have a string value and an integer value, respectively.
* So, you can access the arguments like below:
*/
string arg1 = arguments.FindStringArgument("example_arg1");
LOG(INFO) << "example_arg1: " << arg1;
int64_t arg2 = arguments.FindIntegerArgument("example_arg2");
LOG(INFO) << "example_arg2: " << arg2;
// You can override gflag like this: ./my_project-local --example_arg3=hahaha
LOG(INFO) << "example_arg3: " << FLAGS_example_arg3;
/*
* Registers various handlers.
* You may be interesed in this function and handlers in it.
* Please see "event_handlers.cc"
*/
my_project::RegisterEventHandlers();
return true;
}
}
|
server.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | namespace MyProject
{
public class Server
{
public static void Install(ArgumentMap arguments)
{
// Session open, close handlers.
NetworkHandlerRegistry.RegisterSessionHandler (
new NetworkHandlerRegistry.SessionOpenedHandler (OnSessionOpened),
new NetworkHandlerRegistry.SessionClosedHandler (OnSessionClosed));
// "echo" message handler for JSON type.
NetworkHandlerRegistry.RegisterMessageHandler ("echo", new NetworkHandlerRegistry.JsonMessageHandler (OnEcho));
// "echo_pbuf" message handler for Google Protocol Buffers.
NetworkHandlerRegistry.RegisterMessageHandler ("echo_pbuf", new NetworkHandlerRegistry.ProtobufMessageHandler (OnEchoPbuf));
// Parameters specified in the "arguments" section in your MANIFEST.json
// will be passed in the variable "arguments".
// So, you can give configuration data to your game server.
//
// Example:
//
// We have in MANIFEST.json "example_arg1" and "example_arg2" that
// have a string value and an integer value, respectively.
// So, you can access the arguments like below:
string arg1 = arguments.FindString ("example_arg1");
Log.Info ("example_arg1: {0}", arg1);
Int64 arg2 = arguments.FindInteger ("example_arg2");
Log.Info ("example_arg2: {0}", arg2);
// You can override gflag like this: ./mono-local --example_arg3=hahaha
Log.Info("example_arg3: {0}", Flags.GetString ("example_arg3"));
// Registers a timer.
//
// Below demonstrates a repeating timer. One-shot timer is also available.
// Please see the Timer class.
Timer.ExpireRepeatedly(WallClock.FromSec(1), OnTick);
}
}
}
|
43.2. 方法2: 通过Google Flag添加¶
43.2.1. 添加Google Flag¶
首先利用 Google Gflag ,在代码中定义要使用的运行参数。
此时使用的函数如下所示。
DEFINE_bool |
boolean |
DEFINE_int32 |
32-bit integer |
DEFINE_int64 |
64-bit integer |
DEFINE_uint64 |
unsigned 64-bit integer |
DEFINE_double |
double |
DEFINE_string |
C++ string |
示例如下所示。
DEFINE_string(my_arg1, "기본값", "my_arg1에 대한 설명");
Note
对于C#,须要通过C++代码在src/{{project_name}}_server.cc中添加,而不是在mono/server.cs中添加。
43.2.2. 从服务器代码读取flag¶
当需要相应flag时,通过与DEFINE_XYZ()匹配的DECLARE_XYZ()函数 声明 flag,然后在代码中以 FLAGS_XYZ 的名字使用即可。
可使用的DECLARE_XYZ()函数如下所示。
DECLARE_bool |
boolean |
DECLARE_int32 |
32-bit integer |
DECLARE_int64 |
64-bit integer |
DECLARE_uint64 |
unsigned 64-bit integer |
DECLARE_double |
double |
DECLARE_string |
C++ string |
my_project_server.cc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | // You can differentiate game server flavors.
DECLARE_string(example_arg3);
class MyProjectServer : public Component {
public:
static bool Install(const ArgumentMap &arguments) {
LOG(INFO) << "Built using Engine version: " << FUNAPI_BUILD_IDENTIFIER;
// Kickstarts the Engine's ORM.
// Do not touch this, unless you fully understand what you are doing.
my_project::ObjectModelInit();
/*
* Parameters specified in the "arguments" section in your MANIFEST.json
* will be passed in the variable "arguments".
* So, you can give configuration data to your game server.
*
* Example:
*
* We have in MANIFEST.json "example_arg1" and "example_arg2" that
* have a string value and an integer value, respectively.
* So, you can access the arguments like below:
*/
string arg1 = arguments.FindStringArgument("example_arg1");
LOG(INFO) << "example_arg1: " << arg1;
int64_t arg2 = arguments.FindIntegerArgument("example_arg2");
LOG(INFO) << "example_arg2: " << arg2;
// You can override gflag like this: ./my_project-local --example_arg3=hahaha
LOG(INFO) << "example_arg3: " << FLAGS_example_arg3;
/*
* Registers various handlers.
* You may be interesed in this function and handlers in it.
* Please see "event_handlers.cc"
*/
my_project::RegisterEventHandlers();
return true;
}
}
|
需要相应flag时,可以以**Flags.GetString(“XYZ”)**的形式读取值。
此时,各类型可Get的函数如下。
GetBool |
boolean |
GetInt32 |
32-bit integer |
GetInt64 |
64-bit integer |
GetUInt64 |
unsigned 64-bit integer |
GetDouble |
double |
GetString |
C# string |
server.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | namespace MyProject
{
public class Server
{
public static void Install(ArgumentMap arguments)
{
// Session open, close handlers.
NetworkHandlerRegistry.RegisterSessionHandler (
new NetworkHandlerRegistry.SessionOpenedHandler (OnSessionOpened),
new NetworkHandlerRegistry.SessionClosedHandler (OnSessionClosed));
// "echo" message handler for JSON type.
NetworkHandlerRegistry.RegisterMessageHandler ("echo", new NetworkHandlerRegistry.JsonMessageHandler (OnEcho));
// "echo_pbuf" message handler for Google Protocol Buffers.
NetworkHandlerRegistry.RegisterMessageHandler ("echo_pbuf", new NetworkHandlerRegistry.ProtobufMessageHandler (OnEchoPbuf));
// Parameters specified in the "arguments" section in your MANIFEST.json
// will be passed in the variable "arguments".
// So, you can give configuration data to your game server.
//
// Example:
//
// We have in MANIFEST.json "example_arg1" and "example_arg2" that
// have a string value and an integer value, respectively.
// So, you can access the arguments like below:
string arg1 = arguments.FindString ("example_arg1");
Log.Info ("example_arg1: {0}", arg1);
Int64 arg2 = arguments.FindInteger ("example_arg2");
Log.Info ("example_arg2: {0}", arg2);
// You can override gflag like this: ./mono-local --example_arg3=hahaha
Log.Info("example_arg3: {0}", Flags.GetString ("example_arg3"));
// Registers a timer.
//
// Below demonstrates a repeating timer. One-shot timer is also available.
// Please see the Timer class.
Timer.ExpireRepeatedly(WallClock.FromSec(1), OnTick);
}
}
}
|
43.2.3. 运行命令行时传输参数¶
现在游戏服务器将识别到名为 --example_arg3
的运行参数。即,将通过 --example_arg3=my_value
的形式予以使用。
$ ./my_game_server-local --example_arg3=my_value
也可以在EXTRA_ARGS环境变量中列出将要添加的参数。
$ EXTRA_ARGS="--my_arg1=my_value" ./my_game_server-local
或
$ export EXTRA_ARGS="--my_arg1=my_value"
$ ./my_game_server-local
43.2.4. 作为Service运行时传输参数¶
当游戏服务器打包后作为Service运行时,和前面提到的一样,无法传输运行参数。 此时,可在 设置服务 中提到的文件中定义运行参数后传输。
Upstart:
在 etc/upstart/default/{{project-name}} 文件中以 export EXTRA_ARGS="--example_arg3=my_value --example_arg4=another"
的形式输入。
Important
必须带有 export
, EXTRA_ARGS
后面的 =
前后不能有空格。
Systemd:
在*etc/systemd/{{project-name}}*文件中以 EXTRA_ARGS="--example_arg3=my_value --example_arg4=another"
的形式输入。
Important
编写时不能有 export
。