- 理解端口的概念
- 做了一个状态判断让客户端/服务器知道应该做什么
- 通过指定的端口和IP让Client连接上Server
知识储备
我们需要之前写过的Server和Client脚本,具体请参见:→戳我
理解一个新的概念RPC。
—————————————————————————————————————————
是不是十分眼熟?NONONO这可不是People‘s Republic of China PRC,这是一种通过网络从远程计算机程序上请求服务而不需要了解底层网络技术的协议。
他的工作原理大概为
1.调用客户端句柄;执行传送参数
2.调用本地系统内核发送网络消息 3.消息传送到远程主机4.服务器句柄得到消息并取得参数
5.执行远程过程
6.执行的过程将结果返回服务器句柄
7.服务器句柄返回结果,调用远程系统内核 8.消息传回本地主机 9.客户句柄由内核接收消息10.客户接收句柄返回的数据
我们可以理解为,Client有一堆对参数,Server有一个函数,我们从Client发起请求将参数传过去,在Server端调用函数用来运算这些参数,然后得出结果返回给CLient端口。
简单来说,RPC在OSI网络通信模型中,跨越了传输层和应用程序。使得网络开发更加便捷。
—————————————————————————————————————————
而在Unity中设置RPC方法的属性有这样的说明
1,在所有连接端调用一个RPC函数。
2,调用的函数必须有@RPC标识([RPC]用于C#)。NetworkView必须附加到GameObject上,RPC函数才能够被调用。NetworkView用于其他地方或者是仅用于RPC函数是没有关系的。如果仅用于RPC函数,stateSynchronization应该被关掉,并且Ovserved属性设置为none,在整个场景中RPC函数的名称应该是唯一的,如果不同脚本的两个RPC函数具有相同的名称,仅有一个会被调用。RPC调用总是确保执行的顺序与他们调用的顺序相同。用NetworkView.group为NetworkView设置的通信组,被用于RPC调用。为了获取RPC自身的信息,可以添加一个NetworkMessageInfo参数到函数声明中,它将自动包含这个信息。这样的做的时候你不需要改变调用RPC函数的方式,可以参考手册中的RPC部分以便获取更多关于RPC的信息。可用的RPC参数为int,float,string,NetworkPlayer,NetworkViewID,Vector3和Quaternion。
概括成一句话,在你想用RPC传输的S/C端口,都应该有一个同样的RPC函数,还要用【RPC】标注起来。
好吧这里就算不能理解也没有关系,我们在实际调用到的时候就能慢慢理解了
改写代码
Server
GUILayOut.Box(msn);
这就生成了一个装载着msn的小矩形盒子。
接下来我们就要给服务器端配置上RPC函数,记住这个RPC函数在所有端都应该一致,如果在不同端存在着同名的不同RPC函数,将只调用一个。写入下列代码
[RPC]//一定要记得标注这个标记
void ReceiveMessage(string msg,NetWorkMessageInfo info)
{
msn = "Sender"+info.sender +"Message"+msg +"Time"+info.timestep;
}
//将发送者信息,发送的字符串,发送时间 打包给 msn
然后运行一下。
如果没有什么意外的话(就加了这么点代码都有意外我直接跳楼算了= =)会看到如下界面
Client
打开Client脚本。同样的我们需要新建一个字符串变量来储存文本信息,并且初始化为空
string msn = “”;
我们回忆一下以前的版本,上一次,我们的客户端的功能仅仅是按下按钮,连接到服务器,并没有更多需求,现在,我们需要在客户端输入文本,所以在状态判断中我们需要做一下改动
void OnGUI()
{
switch(NetWork.peerType)
{
case NetworkPeerType(Diconnected):
StartConnect();
break;
case NetworkPeerType(Connecting)
break;
case NetworkPeerType(Server)
break;
case NetworkPeerType(Client)
OnClient;//我们新定义一个函数用于实现输入功能
break;
}
}
//然后实现这个新功能
void OnClient()
{
msn = GUILayout.TextArea(msn);
if(GUILayout.Button("Send")
{
networkView.RPC("ReceiveMessage",RPCMode.All, msn);
}
}
//同样的我们需要配置RPC函数,直接将Server端的函数复制过来
[RPC]
void ReceiveMessage(string msg, NetWorkInfo info)
{
msn = "Sender"+ info.sender +"Message"+msg +"Time" +info.timestamp;
}
列了这么一大堆代码肯定看着就烦吧= =没关系我们来细说明一下。
第一个函数,在状态判断中,给(目前是Client状态)添加了一个功能(该功能用于输入)
第二个函数,实现输入功能,直接调用了Unity GUI的自带输入框TextArea,然后执行了一个判断,按下send按钮之后调用RPC函数。
第三个就是习以为常的配置RPC函数了。
这么一分析,最重要的就是第二个函数中的那个NetWorkVIew.RPC()函数,这个函数的功能时调用所有连接端的RPC函数
这个函数有三个参数分别为
需要调用的RPC函数名
RPC模式(全部,仅客户端,其他,全部缓存)
发送给RPC函数的的参数
这样是不是就理解了呢,我们将它拖拽到Camera上,然后删掉Server的脚本。保存并运行,连接后你会看到如下
现在输入文本并按下发送
服务器端口就会准确的显示发送端口,发送文本了
总结
好了,到目前为止,我们已经完成如下任务
- 理解了RPC的消息传输运作原理
- 实现了单向发送文本的功能
确切来说,与其将他称之为一个Unity版本的QQ,更不如说他是一个游戏中常见的小喇叭系统。
那么为了完成一个QQ,我们应该完成消息的双向交流,这个作为课下思考,我们下一次会详细讲解。
那么明天见~
————————————————————————————
最后为懒人用户提供现成的代码和示例程序