您的位置:首页 > 移动开发 > Unity3D

Unity结合C++开发服务器实现多人游戏(四)

2017-02-21 11:03 615 查看
服务器消息制作

在ProudNet接收信息时可以使用多种方法,其中之一是使用RMI.
因为通过RMI接收信息由机器代码进行自动转换,所以在程序开发中可以避免不必要的失误。
在服务器端添加一个新的PIDL文件,PIDL文件使用Visual Studio
Addon会很方便.
详细可参考 PIDL-addon 编译器.
PIDL文件以接收信息函数形式表现,此函数可进行直接调用.
PIDL 文件中生成proxy和 stub代码.
Proxy代表信息发送stub代表信息接收. 
Proxy的函数调用时,输入至少一个以上"运行此函数设备的HostID",包含此函数的其它设备在
stub中运行.以远程调用的形式接收消息.
新的PIDL文件Simple.PIDL添加至运行的程序中.服务器与客户端共同使用的类库添加到项目或者添加到服务器项目.
rename cs(std::wstring, System.String);
 
global Simple 1000
{
    RequestLogin([in] std::wstring id, [in] std::wstring password);
 
    NotifyLoginSuccess();
    NotifyLoginFailed([in] std::wstring reason);
}
第一行rename的意思是, "C#中std::wstring可以替换为System.String".
RequestLogin, NotifyLoginSuccess, NotifyLoginFailed分别指的是 "与服务器的连接邀请"
"与服务器连接成功" "与服务器连接失败".
进行编译后生成Simple.Proxy, Simple.Stub类.创建对象实例包含了服务器和客户端.
Proxy为成员变数. Stub直接继承服务器类.
class SimpleServer
    :public Simple::Stub
{
public:
    Simple::Proxy m_proxy;
在NetServer.Start运行之前, proxy和
stub对象添加到 NetServer.
m_netServer->AttachProxy(&m_proxy);
m_netServer->AttachStub(this);
 
客户端也添加proxy和 stub.并且添加到NetManager.cs.
Simple.Proxy m_proxy = new Simple.Proxy();
Simple.Stub m_stub = new Simple.Stub();
在调用NetClient.Connect之前 proxy, stub添加到
NetClient对象.
m_netClient.AttachProxy(m_proxy);
m_netClient.AttachStub(m_stub);
客户端连接服务器成功的话,可直接调用远程函数RequestLogin.
m_netClient.JoinServerCompleteHandler =
    (ErrorInfo info, ByteArray replyFromServer) =>
{
    if (info.errorType == ErrorType.ErrorType_Ok)
    {
        m_proxy.RequestLogin(HostID.HostID_Server,
            RmiContext.SecureReliableSend, m_userID, m_password); // (1)
        m_state = MyState.Connecting;
(1)代表的意义如下.
§  向服务器发送信息.
§  加密后发送. 
§  发送输入的userID和 password.
 
服务器接收RequestLogin并处理. PIDL编译结果包含远程函数声明和构建C
macro.
class SimpleServer
{
    DECRMI_Simple_RequestLogin; 
然后添加进行处理的函数RequestLogin.
DEFRMI_Simple_RequestLogin(SimpleServer)
{
    cout << "RequestLogin " << StringT2A(id.c_str()) << " "
        << StringT2A(password.c_str()) << endl;
    // success!
    m_proxy.NotifyLoginSuccess(remote, RmiContext::ReliableSend);
    return true;
}
ProudNet的远程函数即,RMI函数需要一直是return true.
分析以上函数代码,存在变量remote, id, password.
id,password是PIDL中所定义的, remote是
"远程函数调用,信息发送设备的HostID.
首先,假设以上函数"一定登陆成功
在服务器中发送了NotifyLoginSuccess,客户端添加进行可处理的代码.
m_stub.NotifyLoginSuccess = (HostID remote, RmiContext rmiContext) =>
{
    m_state = MyState.Connected;
 
    return true;
};
m_stub.NotifyLoginFailed = (HostID remote, RmiContext rmiContext, System.String reason) =>
{
    Debug.Log(reason);
    m_disconnectNow = true;
    return true;
};
对以上代码进行说明
§  "登陆成功"接收远程函数调用后,转换为MyState.Connected同时隐藏登录窗口.
§  接收"登陆失败"后,输出失败的理由并断开连接.
注意:Client.Disconnect在 RMI事件处理函数中无法被调用.
使用以上变数或者其它方法调用Disconnect函数.
class NetManager
{
    void Update()
    {
        if (m_disconnectNow)
        {
            m_netClient.Disconnect();
            m_state = MyState.Disconnected;
            m_disconnectNow = false;
        }
现在,运行客户端和服务器点击Connect键.客户端的GUI消失的话,代表服务器输出
RequestLogin,连接成功.
 
在此我们只使用远程函数变量int, string的基本类型,也可根据大家定义的构造体或者array进行接收.
详细请参考PIDL的数据类型及Marshaling

第五篇:Unity结合C++开发服务器实现多人游戏(五)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: