/// <summary> /// タイムアウト付でリクエストを出します。 /// </summary> public void SendRequest <TReq, TRes>(TReq request, TimeSpan timeout, PbResponseHandler <TRes> handler, bool isOutLog = true) where TReq : class { if (request == null) { return; } var sendData = new PbSendData(request); var id = GetNextSendId(); var reqData = new PbRequestData <TReq, TRes>() { Id = id, Connection = this, ResponseReceived = handler, }; reqData.SetTimeout(timeout); // 未処理のリクエストとして、リストに追加します。 lock (this.requestDataDic) { this.requestDataDic.Add(id, reqData); } // データを送信します。 SendDataInternal(id, false, sendData, isOutLog); }
/// <summary> /// protobufでシリアライズ後のデータを直接送ります。 /// </summary> public void SendData(PbSendData sendData, bool isOutLog = true) { if (sendData == null) { return; } var id = GetNextSendId(); SendDataInternal(id, false, sendData, isOutLog); }
/// <summary> /// レスポンスを送ります。 /// </summary> private void SendResponse(int id, IPbResponse response, bool isOutLog = true) { if (response == null) { return; } var sendData = new PbSendData(response); SendDataInternal(id, true, sendData, isOutLog); }
/// <summary> /// コマンドを送ります。 /// </summary> public void SendCommand <TCmd>(TCmd command, bool isOutLog = true) where TCmd : class { if (command == null) { return; } var sendData = new PbSendData(command); SendData(sendData, isOutLog); }
/// <summary> /// コンストラクタ /// </summary> public NeedAckInfo(PbConnection connection, DataId dataId, PbSendData sendData, TimeSpan timeout) { DataId = dataId; SendData = sendData; Timeout = timeout; this.connection = connection; this.timer = new Timer( Timer_Callback, null, timeout, TimeSpan.FromMilliseconds(-1)); }
/// <summary> /// データを送信します。 /// </summary> private void SendDataInternal(int id, bool isResponse, PbSendData pbSendData, bool isOutLog) { if (pbSendData == null) { throw new ArgumentNullException("pbSendData"); } if (pbSendData.SerializedData == null || pbSendData.EncodedTypeName == null) { throw new PbException("送信データがシリアライズされていません。"); } try { if (!IsConnected || !CanWrite) { // これをthrowすると対処が面倒なので return; } var typedata = pbSendData.EncodedTypeData; var payload = pbSendData.SerializedData; // パケットヘッダを用意します。 var header = new PbPacketHeader { Id = id, IsResponse = isResponse, TypeNameLength = typedata.Length, PayloadLength = payload.Length, }; var headerData = header.GetEncodedPacket(); // 送信データは複数バッファのまま送信します。 var sendData = new SendData() { Socket = this.Socket, }; sendData.AddBuffer(headerData); sendData.AddBuffer(typedata); sendData.AddBuffer(payload); // データを送信します。 base.SendData(sendData); if (isOutLog) { Log.Debug(this, "{0}を送信しました。(content={1}bytes)", pbSendData.TypeName, (payload != null ? payload.Length : -1)); } } catch (Exception ex) { Log.ErrorException(this, ex, "{0}: 送信データのシリアライズに失敗しました。", pbSendData.TypeName); } }