using System;
using System.Collections.Generic;
using Common.Base;
using Common.Network;
using MongoDB.Bson;
using TNet;
using UNet;
namespace Model
{
///
/// gate对外连接使用
///
public class GateNetworkComponent: Component, IUpdate, IStart
{
private IService service;
private readonly Dictionary unitIdChannels =
new Dictionary();
private void Accept(string host, int port, NetworkProtocol protocol = NetworkProtocol.TCP)
{
switch (protocol)
{
case NetworkProtocol.TCP:
this.service = new TService(host, port);
break;
case NetworkProtocol.UDP:
this.service = new UService(host, port);
break;
default:
throw new ArgumentOutOfRangeException("protocol");
}
this.AcceptChannel();
}
public void Start()
{
this.Accept(World.Instance.Options.GateHost, World.Instance.Options.GatePort,
World.Instance.Options.Protocol);
}
public void Update()
{
this.service.Update();
}
///
/// 接收连接
///
private async void AcceptChannel()
{
while (true)
{
AChannel channel = await this.service.GetChannel();
channel.OnDispose += this.OnChannelDispose;
ProcessChannel(channel);
}
}
///
/// 接收分发封包
///
///
private static async void ProcessChannel(AChannel channel)
{
while (true)
{
byte[] messageBytes = await channel.RecvAsync();
Opcode opcode = (Opcode)BitConverter.ToUInt16(messageBytes, 0);
if (!OpcodeHelper.IsClientMessage(opcode))
{
continue;
}
ObjectId unitId = channel.GetComponent().UnitId;
Actor actor = World.Instance.GetComponent().Get(unitId);
actor.Add(messageBytes);
}
}
// channel删除的时候需要清除与unit id的关联
private void OnChannelDispose(AChannel channel)
{
ChannelUnitInfoComponent channelUnitInfoComponent =
channel.GetComponent();
if (channelUnitInfoComponent != null)
{
this.unitIdChannels.Remove(channelUnitInfoComponent.UnitId);
}
}
// 将unit id与channel关联起来
public void AssociateUnitIdAndChannel(ObjectId id, AChannel channel)
{
this.unitIdChannels[id] = channel;
}
public void SendAsync(ObjectId id, byte[] buffer)
{
AChannel channel;
if (!this.unitIdChannels.TryGetValue(id, out channel))
{
return;
}
channel.SendAsync(buffer);
}
}
}