FastSocket这个东西上次我已经说过,它使用简单,功能强大,扩展灵活,目前在新浪的生产环境中已经被广泛使用,所以它的性能,安全等各方面我们绝对可以信赖,今天我们来说一个话题,和上一讲有关,这次我们制作一个基于FastSocket的传输协议,它的意义重大,当fastSocket提供的协议不能满足项目要求时,我们就必须硬着头皮去自己写了,还好,fastsocket为我们铺好了路,我们只要按着这条路走下去,就可以了。
自定义的协议格式如下
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0YAAAAmCAIAAABvWhyIAAAFTklEQVR4nO2WSxbiOgxEWQoLf5vsGcMevRw6tsolJQGbXM6dxDj6lMugx+vPfwAAAACwNI+vVwAAAAAAB2GkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5emPdM//P1+v71vo3i9VZhd8dxbfOpobtoywk8Ml/a7CM4AHfpXJpbuivNY//lvb5nCk66bJJltOUCf+u+h+hc+3j17sRo6SRhHMfrcXn/9+pm1Z1+nXljVD+8mqrbOkhBWKHfFSezrdaI5hapoXzmV+YcW2i3BKLaj9rQg65hIe2EU45XLVxL+V9/yCC1I7m1PBTVcPX2ekS2tqphbRtnvrZ3f+LY74QIf6pZazylyariDsy/53SQkb7RT/Op+X6zXyzITC3vxvFQ+InUcuV038W3mvkMVP6uxMBTddPXzdGulejVPfH9s7sFvRj7sgOrLuuRvEzNg+Ri92lTmleOcxKkbrIESOQomM87S8q0fYQNfZnn63F/EolBFJjwgrZDF1HkZohW0XRYQoZtvgULTuuYgX5xFWBBRS7DakpGsPqHtkkaTZoxEp8IAWod2fkjFbXuoEh0JFes7jvYJ62hjPfz/DU4661lJEsuh+t8eH6YNuOL9ikaUWxJfPtFfbdfe0utGGO4fFD1sWBZg66GhCz5lbbuvRQRxxagUf91tW2Nauu5t/RNhu/eLu11bmvKTnChvpXHayKZ0paeSB7NF09cEDwxTly+V8FZVxE+8V1DOrHbaQDV4+qfaVh+kDx3m64ihLLcgR+QqXUP9SDHduK5H5ar8U7zGHJtDRRAFTtZy9V13f6nai8kTNB8UvCGt2XRZWdBeJ9huX9HRho4BlJ/vSZc1v6uZfIjwwTFG+XM5XURk38Z6p3vsn26+uwQ9ePqn2lUfKB20bUdG7CO3jthgV3Y0sDqn7SuFssro7O7W8+oSyYX0ddNg5W478ZgZxxBG9RCpFCmgzHxTW6TolrEjRli0Mo1dMcxZqnlPYqAxTiqG1hlmym534w8rxgIjQ7ty9FflHy6iP4J7eG0pUa6096KGLzDhdbzj9bosPYYJu9GEbfj++fMPg12k63OPsjKpy9mRf8XXQYedsedjd8YuXWtyFTZn5oLBO12cJ69z92oop2icv6bnCRmVkXeerFLVvbs4mFZULKfTij3ngisvlfOUctLO4qPcK6mX7TRVWcHX2pF6pkc4vzuynu+JEdlZ8J33gl8J3Z6GAU1oWgs/ccvbgDv5M1LKf66VU176w3Szlu28GnOqSXids1NRQipRKYtH8pTV1S11tPGDq4JRqKjyMeRPvORIdd6OIf9zV2ZN6HRzptpp2lYnH4SsicuuVKI5WJMr4LnH0Yiu33ukI1ZVICB7pYC6+V/6+IgSfp+V2m69JTTGRKGrfjH+KsLqvlJfaIKLfqNMomqhTaNKtJCrvGRz3DMI6akdeMveLZoWkXdGGpzysBA90v4raMWWPFNYbbus9RyI/S7cFHX8YPDJMod9t8VF2yUV8PnU24wcqbFP49qXlD7fg3O0fFvYzICzgAZiTGc56PNLt5sqrq1kr46V17oK3E/pxoQqvr9vypb5qK7+PsFdz80sKLzwA0/P1I945rT/SAQAAAMBCMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALM9fcDvieBUsHLMAAAAASUVORK5CYII=" alt="" />
说干就干
首先,如果要想扩展一个自己的协议,要对 client和server端分别进行开发,下面我们来看一下client的开发
aaarticlea/png;base64,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" alt="" />
我们要添加的类有三个文件组成,分别是DSSBinaryProtocol,DSSBinaryResponse和一个使用这个协议的客户端入口DSSBinarySocketClient
DSSBinaryProtocol
/// <summary>
/// 异步二进制协议
/// 协议格式
/// [Message Length(int32)][SeqID(int32)][ProjectID(int16)][Cmd Length(int16)][VersonNumber Length(int16)][Cmd + VersonNumber + Body Buffer]
/// 其中参数TableName和VersonNumber长度为40,不够自动在左侧补空格
/// </summary>
public sealed class DSSBinaryProtocol : IProtocol<DSSBinaryResponse>
{ #region IProtocol Members
/// <summary>
/// find response
/// </summary>
/// <param name="connection"></param>
/// <param name="buffer"></param>
/// <param name="readlength"></param>
/// <returns></returns>
/// <exception cref="BadProtocolException">bad async binary protocl</exception>
public DSSBinaryResponse FindResponse(IConnection connection, ArraySegment<byte> buffer, out int readlength)
{
if (buffer.Count < ) { readlength = ; return null; } //获取message length
var messageLength = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset);
if (messageLength < ) throw new BadProtocolException("bad async binary protocl"); readlength = messageLength + ;
if (buffer.Count < readlength) { readlength = ; return null; } var seqID = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset + );
var projectID = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var flagLength = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var versonLength = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var strName = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + , flagLength);
var versonNumber = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + + flagLength, versonLength); var dataLength = messageLength - - flagLength - versonLength;
byte[] data = null;
if (dataLength > )
{
data = new byte[dataLength];
Buffer.BlockCopy(buffer.Array, buffer.Offset + + flagLength + versonLength, data, , dataLength);
}
return new DSSBinaryResponse(seqID, projectID, strName, versonNumber, data);
}
#endregion
}
DSSBinaryResponse
/// <summary>
/// 数据同步系统DSS使用的Socket协议,我们称为DSSBinary协议
/// [Message Length(int32)][SeqID(int32)][ProjectID(int16)][Cmd Length(int16)][VersonNumber Length(int16)][Cmd + VersonNumber + Body Buffer]
/// </summary>
public class DSSBinaryResponse : IResponse
{
/// <summary>
/// 流水ID
/// </summary>
public int SeqID { get; private set; }
/// <summary>
/// 项目类型编号
/// </summary>
public short ProjectID { get; set; }
/// <summary>
/// 本次传输的版本号,所有客户端唯一[项目名称(4字节)+guid(36字节)]
/// </summary>
public string VersonNumber { get; private set; }
/// <summary>
/// 命令名称
/// </summary>
public string Flag { get; private set; } /// <summary>
/// 要操作的表对象,以字节数组形式进行传输
/// </summary>
public readonly byte[] Buffer = null; public DSSBinaryResponse(int seqID,
short projectID,
string flag,
string versonNumber,
byte[] buffer)
{
this.SeqID = seqID;
this.ProjectID = projectID;
this.VersonNumber = versonNumber;
this.Flag = flag;
this.Buffer = buffer;
}
}
DSSBinarySocketClient
/// <summary>
/// 异步socket客户端
/// </summary>
public class DSSBinarySocketClient : PooledSocketClient<DSSBinaryResponse>
{
#region Constructors
/// <summary>
/// new
/// </summary>
public DSSBinarySocketClient()
: base(new DSSBinaryProtocol())
{
}
/// <summary>
/// new
/// </summary>
/// <param name="socketBufferSize"></param>
/// <param name="messageBufferSize"></param>
public DSSBinarySocketClient(int socketBufferSize, int messageBufferSize)
: base(new DSSBinaryProtocol(), socketBufferSize, messageBufferSize, , )
{
}
/// <summary>
/// new
/// </summary>
/// <param name="socketBufferSize"></param>
/// <param name="messageBufferSize"></param>
/// <param name="millisecondsSendTimeout"></param>
/// <param name="millisecondsReceiveTimeout"></param>
public DSSBinarySocketClient(int socketBufferSize,
int messageBufferSize,
int millisecondsSendTimeout,
int millisecondsReceiveTimeout)
: base(new DSSBinaryProtocol(),
socketBufferSize,
messageBufferSize,
millisecondsSendTimeout,
millisecondsReceiveTimeout)
{
}
#endregion #region Public Methods public Task<TResult> Send<TResult>(string cmdName, short projectID, string versonNumber, byte[] payload,
Func<DSSBinaryResponse, TResult> funcResultFactory, object asyncState = null)
{
return this.Send(null, cmdName, projectID, versonNumber, payload, funcResultFactory, asyncState);
} public Task<TResult> Send<TResult>(byte[] consistentKey, string cmdName, short projectID, string versonNumber, byte[] payload,
Func<DSSBinaryResponse, TResult> funcResultFactory, object asyncState = null)
{
if (string.IsNullOrEmpty(cmdName)) throw new ArgumentNullException("cmdName");
if (funcResultFactory == null) throw new ArgumentNullException("funcResultFactory"); var seqID = base.NextRequestSeqID();
var cmdLength = cmdName.Length;
var versonNumberLength = versonNumber.Length;
var messageLength = (payload == null ? : payload.Length) + cmdLength + versonNumberLength + ;
var sendBuffer = new byte[messageLength + ]; //write message length
Buffer.BlockCopy(NetworkBitConverter.GetBytes(messageLength), , sendBuffer, , );
//write seqID.
Buffer.BlockCopy(NetworkBitConverter.GetBytes(seqID), , sendBuffer, , );
//write proejctID
Buffer.BlockCopy(NetworkBitConverter.GetBytes(projectID), , sendBuffer, , );
//write response flag length.
Buffer.BlockCopy(NetworkBitConverter.GetBytes((short)cmdLength), , sendBuffer, , );
//write verson length
Buffer.BlockCopy(NetworkBitConverter.GetBytes((short)versonNumberLength), , sendBuffer, , );
//write response cmd
Buffer.BlockCopy(Encoding.ASCII.GetBytes(cmdName), , sendBuffer, , cmdLength);
//write response versonNumber
Buffer.BlockCopy(Encoding.ASCII.GetBytes(versonNumber), , sendBuffer, + cmdLength, versonNumberLength);
//write body buffer
if (payload != null && payload.Length > )
Buffer.BlockCopy(payload, , sendBuffer, + cmdLength + versonNumberLength, payload.Length); var source = new TaskCompletionSource<TResult>(asyncState);
base.Send(new Request<DSSBinaryResponse>(consistentKey, seqID, cmdName, sendBuffer,
ex => source.TrySetException(ex),
response =>
{
TResult result;
try { result = funcResultFactory(response); }
catch (Exception ex) { source.TrySetException(ex); return; } source.TrySetResult(result);
}));
return source.Task;
}
#endregion
}
然后,我们再来说一下server端的开发,它有两个文件组成,分别是DSSBinaryCommandInfo,DSSBinaryProtocol
aaarticlea/png;base64,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" alt="" />
DSSBinaryCommandInfo
/// <summary>
/// async binary command info.
/// </summary>
public class DSSBinaryCommandInfo : ICommandInfo
{
#region Constructors
/// <summary>
/// new
/// </summary>
/// <param name="cmdName"></param>
/// <param name="seqID"></param>
/// <param name="buffer"></param>
/// <exception cref="ArgumentNullException">cmdName is null or empty.</exception>
public DSSBinaryCommandInfo(int seqID, short projectID, string cmdName, string versonNumber, byte[] buffer)
{
if (string.IsNullOrEmpty(cmdName)) throw new ArgumentNullException("cmdName");
if (string.IsNullOrEmpty(versonNumber)) throw new ArgumentNullException("versonNumber"); this.VersonNumber = versonNumber;
this.CmdName = cmdName;
this.SeqID = seqID;
this.ProjectID = projectID;
this.Buffer = buffer;
}
#endregion #region Public Properties
/// <summary>
/// 版本号
/// </summary>
public string VersonNumber
{
get;
private set;
}
public short ProjectID { get; private set; }
/// <summary>
/// get the current command name.
/// </summary>
public string CmdName
{
get;
private set;
}
/// <summary>
/// seq id.
/// </summary>
public int SeqID
{
get;
private set;
}
/// <summary>
/// 主体内容
/// </summary>
public byte[] Buffer
{
get;
private set;
}
#endregion #region Public Methods
/// <summary>
/// reply
/// </summary>
/// <param name="connection"></param>
/// <param name="payload"></param>
public void Reply(IConnection connection, byte[] payload)
{
var packet = PacketBuilder.ToDSSBinary(this.SeqID, this.ProjectID, this.CmdName, this.VersonNumber, payload);
connection.BeginSend(packet);
}
#endregion }
DSSBinaryProtocol
/// <summary>
/// 数据中心二进制协议
/// 协议格式
/// [Message Length(int32)][SeqID(int32)][Request|Response Flag Length(int16)][VersonNumber Length(int16)][Request|Response Flag + VersonNumber + Body Buffer]
/// </summary>
public sealed class DSSBinaryProtocol : IProtocol<DSSBinaryCommandInfo>
{
#region IProtocol Members
/// <summary>
/// find command
/// </summary>
/// <param name="connection"></param>
/// <param name="buffer"></param>
/// <param name="maxMessageSize"></param>
/// <param name="readlength"></param>
/// <returns></returns>
/// <exception cref="BadProtocolException">bad async binary protocl</exception>
public DSSBinaryCommandInfo FindCommandInfo(IConnection connection, ArraySegment<byte> buffer,
int maxMessageSize, out int readlength)
{
if (buffer.Count < ) { readlength = ; return null; } var payload = buffer.Array; //获取message length
var messageLength = NetworkBitConverter.ToInt32(payload, buffer.Offset);
if (messageLength < ) throw new BadProtocolException("bad async binary protocl");
if (messageLength > maxMessageSize) throw new BadProtocolException("message is too long"); readlength = messageLength + ;
if (buffer.Count < readlength)
{
readlength = ; return null;
} var seqID = NetworkBitConverter.ToInt32(payload, buffer.Offset + );
var projectID = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var cmdNameLength = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var versonNumberLength = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var strName = Encoding.UTF8.GetString(payload, buffer.Offset + , cmdNameLength);
var versonNumber = Encoding.UTF8.GetString(payload, buffer.Offset + + cmdNameLength, versonNumberLength); var dataLength = messageLength - - cmdNameLength;
byte[] data = null;
if (dataLength > )
{
data = new byte[dataLength];
Buffer.BlockCopy(payload, buffer.Offset + + cmdNameLength + versonNumberLength, data, , dataLength);
}
return new DSSBinaryCommandInfo(seqID, projectID, strName, versonNumber, data);
}
#endregion
}
除了上面两个文件外,我们还要修改服务端的管理类
/// <summary>
/// Socket server manager.
/// </summary>
public class SocketServerManager
{
#region Private Members
static private readonly List<SocketBase.IHost> _listHosts = new List<SocketBase.IHost>();
#endregion #region Static Methods
/// <summary>
/// 初始化Socket Server
/// </summary>
static public void Init()
{
Init("socketServer");
}
/// <summary>
/// 初始化Socket Server
/// </summary>
/// <param name="sectionName"></param>
static public void Init(string sectionName)
{
if (string.IsNullOrEmpty(sectionName)) throw new ArgumentNullException("sectionName");
Init(ConfigurationManager.GetSection(sectionName) as Config.SocketServerConfig);
}
/// <summary>
/// 初始化Socket Server
/// </summary>
/// <param name="config"></param>
static public void Init(Config.SocketServerConfig config)
{
if (config == null) throw new ArgumentNullException("config");
if (config.Servers == null) return; foreach (Config.Server serverConfig in config.Servers)
{
//inti protocol
var objProtocol = GetProtocol(serverConfig.Protocol);
if (objProtocol == null) throw new InvalidOperationException("protocol"); //init custom service
var tService = Type.GetType(serverConfig.ServiceType, false);
if (tService == null) throw new InvalidOperationException("serviceType"); var serviceFace = tService.GetInterface(typeof(ISocketService<>).Name);
if (serviceFace == null) throw new InvalidOperationException("serviceType"); var objService = Activator.CreateInstance(tService);
if (objService == null) throw new InvalidOperationException("serviceType"); //init host.
var host = Activator.CreateInstance(typeof(SocketServer<>).MakeGenericType(
serviceFace.GetGenericArguments()),
objService,
objProtocol,
serverConfig.SocketBufferSize,
serverConfig.MessageBufferSize,
serverConfig.MaxMessageSize,
serverConfig.MaxConnections) as BaseSocketServer; host.AddListener(serverConfig.Name, new IPEndPoint(IPAddress.Any, serverConfig.Port)); _listHosts.Add(host);
}
}
/// <summary>
/// get protocol.
/// </summary>
/// <param name="protocol"></param>
/// <returns></returns>
static public object GetProtocol(string protocol)
{
switch (protocol)
{
case Protocol.ProtocolNames.AsyncBinary:
return new Protocol.AsyncBinaryProtocol();
case Protocol.ProtocolNames.Thrift:
return new Protocol.ThriftProtocol();
case Protocol.ProtocolNames.CommandLine:
return new Protocol.CommandLineProtocol();
case Protocol.ProtocolNames.DSSBinary:
return new Protocol.DSSBinaryProtocol();
}
return Activator.CreateInstance(Type.GetType(protocol, false));
} /// <summary>
/// 启动服务
/// </summary>
static public void Start()
{
foreach (var server in _listHosts) server.Start();
}
/// <summary>
/// 停止服务
/// </summary>
static public void Stop()
{
foreach (var server in _listHosts) server.Stop();
}
#endregion
}
从上面的代码中,我们看到了自己新加的协议DSSBinary,我们可以在配置文件中对它进行配置,方法和之前说的一样,在这里就不再重复了。
感谢各位的阅读!