-
Notifications
You must be signed in to change notification settings - Fork 577
ServerToServer
ScutGame edited this page Jun 26, 2015
·
6 revisions
此章节介服务端与服务端之间如何通讯
跟服务器打交道时,我们常常会碰到有N台后端服务器,它们之间又需要相互传递数据;
假设场景,有两台服务器A和B,A为游戏的业务服,B为游戏的战斗服务,A需要将玩家数据传给B要如何处理?
-
首先需要确定服务器A和B支持的通讯协议是Http还是Socket,Http是短连接的不能支持双向通讯;
-
确定由服务器A和B哪个做为服务的监听端,哪个做为客户端; 如果B可能会被多个服务依赖,则将B做为服务的监听端;
这里设置服务器B为服务的监听端, 服务器A为客户端;
打开服务器B的项目解决方案, 在Script/CsScript/Remote目录下新建立类Battle,并继承RemoteStruct类,代码如下:
namespace Game.Script.Remote
{
public class Battle : RemoteStruct
{
private int _heroId;
private int _combatNum;
private int _gold;
private List<int> _items = new List<int>();
public Battle(ActionGetter paramGetter, MessageStructure response)
: base(paramGetter, response)
{
}
protected override bool Check()
{
if (httpGet.GetInt("HeroId", ref _heroId) &&
httpGet.GetInt("CombatNum", ref _combatNum))
{
return true;
}
return false;
}
protected override void TakeRemote()
{
var session = ParamGetter.GetSession();
if (session == null)
{
ErrorCode = 10000;
ErrorInfo = "Sessin is null.";
return;
}
//Here to do something
_gold = 100;
}
protected override void BuildPacket()
{
//Send a reward here
response.PushIntoStack(_gold);
response.PushIntoStack(_items.Count);
foreach (var itemId in _items)
{
var dsItem = new MessageStructure();
dsItem.PushIntoStack(itemId);
response.PushIntoStack(dsItem);
}
}
}
}
- Check方法:是接收客户端提交的参数信息较验,与Action的处理机制相同;
- TakeRemote方法:处理请求,产生结果;
- BuildPacket方法:将结果封包下发给客户端;
服务器A做为客户端,需要发起请求,先选择服务器B使用哪种通讯;
private RemoteService httpRemote;
private void Reuest()
{
//创建一个代理类RemoteService的实例,参数:名称和 服务器B的地址
httpRemote = RemoteService.CreateHttpProxy("proxy1", "http://127.0.0.1/service.aspx");
//调用Battle处理,参数:“Battle”是上央服务器B定义的类
var param = new RequestParam();
param.Add("HeroId",1001);
param.Add("CombatNum",100);
httpRemote.Call("Battle", param, successCallback);
}
void successCallback(RemotePackage pack)
{
var reader = new MessageStructure(package.Message as byte[]);
var gold = ms.ReadInt();
var itemsCount = ms.ReadInt();
var items = new int[itemsCount];
for(int i = 0; i < itemsCount; i++)
{
reader.RecordStart();
items[i] = reader.ReadInt();
reader.RecordEnd();
}
}
private RemoteService tcpRemote;
private void Reuest()
{
//创建一个代理类RemoteService的实例,参数:名称,服务器B的地址与端口,心跳检测的间隔时间
tcpRemote = RemoteService.CreateTcpProxy("proxy2", "127.0.0.1", 9001, 30 * 1000);
//调用Battle处理,参数:“Battle”是上央服务器B定义的类
var param = new RequestParam();
param.Add("HeroId",1001);
param.Add("CombatNum",100);
tcpRemote.Call("Battle", param, successCallback);
}
void successCallback(RemotePackage p)
{
var reader = new MessageStructure(package.Message as byte[]);
var gold = ms.ReadInt();
var itemsCount = ms.ReadInt();
var items = new int[itemsCount];
for(int i = 0; i < itemsCount; i++)
{
reader.RecordStart();
items[i] = reader.ReadInt();
reader.RecordEnd();
}
}