/// <summary> /// 处理接收到的数据 /// </summary> /// <param name="args">异步SOCKET事件</param> private void ProcessRecv(SocketAsyncEventArgs args) { if (args.BytesTransferred == 0 || args.SocketError != SocketError.Success) { Stop(); return; } try { int count = args.BytesTransferred; string content = Encoding.UTF8.GetString(args.Buffer, 0, count); CommonBoradcastProtocol obj = JsonConvert.DeserializeObject <CommonBoradcastProtocol>(content); //discard current boradcast object directly when it was an illegal object. if (string.IsNullOrEmpty(obj.Key)) { return; } //dispatch it. Action <CommonBoradcastProtocol> callback; if (!_callbacks.TryGetValue(obj.Key, out callback)) { _tracing.Warn("#We had to discared current boradcast object, because of it hasn't any dispatcher in there."); return; } callback(obj); } catch (System.Exception ex) { _tracing.Error(ex, null); } finally { StartRecv(args); } }
/// <summary> /// 解析元数据 /// </summary> /// <param name="data">总BUFF长度</param> /// <param name="offset">可用偏移量</param> /// <param name="count">可用长度</param> /// <returns> /// 返回能否解析的一个标示 /// </returns> public override List <T> Parse <T>(byte[] data, int offset, int count) { if (data.Length - offset < count) { _tracing.Warn("#Cannot parse segment data, remaining count has no enough!"); return(null); } int protocolId = data[offset + 5]; int serviceId = data[offset + 6]; int detailsId = data[offset + 7]; Type messageType = GetMessageType(protocolId, serviceId, detailsId); if (messageType == null) { _tracing.Error("#Parse message failed, illegal message protocol. #protocol id={0}, service id={1}, detalis id={2}\r\nTarget protocol stack: {3} ", protocolId, serviceId, detailsId, this); return(null); } try { BaseMessage baseMessage = IntellectObjectEngine.GetObject <BaseMessage>(messageType, data, offset, count); return(baseMessage != null ? new List <T> { (T)(object)baseMessage } : null); } catch (System.Exception ex) { _tracing.Error(ex, "#Parse message failed, illegal message protocol. #protocol id={0}, service id={1}, detalis id={2}\r\nTarget protocol stack: {3} ", protocolId, serviceId, detailsId, this); return(null); } }
void Completed(object sender, SocketAsyncEventArgs e) { IFixedCacheStub <NoBuffSocketStub> stub; switch (e.LastOperation) { //send complated event. case SocketAsyncOperation.Send: #region Send Completed. stub = (IFixedCacheStub <NoBuffSocketStub>)e.UserToken; TcpTransportChannel channel = (TcpTransportChannel)stub.Tag; //giveback it at first. ChannelConst.NoBuffAsyncStubPool.Giveback(stub); if (e.SocketError != SocketError.Success && channel.IsConnected) { _tracing.Warn( string.Format( "The target channel SendAsync status has incorrectly, so the framework decided to disconnect it.\r\nL: {0}\r\nR: {1}\r\nSocket-Error: {2}\r\nBytesTransferred: {3}\r\n", channel.LocalEndPoint, channel.RemoteEndPoint, e.SocketError, e.BytesTransferred)); channel.Disconnect(); } #endregion break; //send complated event. case SocketAsyncOperation.Receive: throw new System.Exception("#We can't support NoBuffSocketStub to subscribe the event of Complete for Socket.ReadAsync."); } }
/// <summary> /// 发送一个请求消息 /// </summary> /// <param name="message">请求消息</param> public override void SendRequest(BaseMessage message) { if (message == null) { return; } if (_fixedMsgIdentity) { message.MessageIdentity = _msgIdentity; } message.TransactionIdentity = Identity; message.TransactionIdentity.IsRequest = true; message.ExpireTime = _lease.ExpireTime; message.KPPUniqueId = KPPUniqueId; _request = message; if (!_channel.IsConnected) { _tracing.Warn("Cannot send a response message to {0}, because target msg channel has been disconnected.", _channel.RemoteEndPoint); TransactionManager.Remove(Identity); FailedHandler(null); return; } try { int sendCount; //send failed. if ((sendCount = _channel.Send(message)) < 0) { TransactionManager.Remove(Identity); _channel.Disconnect(); FailedHandler(null); return; } //calc REQ time. RequestTime = DateTime.Now; _tracing.Info("SendCount: {0}\r\nL: {1}\r\nR: {2}\r\n{3}", sendCount, _channel.LocalEndPoint, _channel.RemoteEndPoint, message.ToString()); } catch { TransactionManager.Remove(Identity); _channel.Disconnect(); FailedHandler(null); } }
/// <summary> /// 发送一个请求消息 /// </summary> /// <param name="message">请求消息</param> public override void SendRequest(MetadataContainer message) { if (message == null) { return; } Identity.IsRequest = true; if (_fixedMsgIdentity) { message.SetAttribute(0x00, new MessageIdentityValueStored(_msgIdentity)); } message.SetAttribute(0x01, new TransactionIdentityValueStored(Identity)); message.SetAttribute(0x02, new DateTimeValueStored(_lease.ExpireTime)); message.SetAttribute(0x03, new GuidValueStored(KPPUniqueId)); _request = message; if (!_channel.IsConnected) { _tracing.Warn("Cannot send a response message to {0}, because target msg channel has been disconnected.", _channel.RemoteEndPoint); TransactionManager.Remove(Identity); FailedHandler(null); return; } try { int sendCount; //send failed. if ((sendCount = _channel.Send(message)) < 0) { TransactionManager.Remove(Identity); _channel.Disconnect(); FailedHandler(null); return; } //calc REQ time. RequestTime = DateTime.Now; _tracing.Info("SendCount: {0}\r\nL: {1}\r\nR: {2}\r\n{3}", sendCount, _channel.LocalEndPoint, _channel.RemoteEndPoint, message.ToString()); } catch (System.Exception ex) { TransactionManager.Remove(Identity); _channel.Disconnect(); FailedHandler(null); } }
/// <summary> /// 发送数据 /// <para>* 如果此方法进行发送的元数据,可能是自动分包后的数据。</para> /// </summary> /// <param name="data">要发送的数据</param> /// <returns>返回发送的字节数</returns> protected override int InnerSend(byte[] data) { int sendCount = 1; try { if (_socket == null || !_socket.Connected) { return(-1); } if (data.Length > ChannelConst.MaxMessageDataLength) { _tracing.Warn(string.Format("#Illegal data size: {0}, current allow size: {1}", data.Length, ChannelConst.MaxMessageDataLength)); return(-1); } //get fixed cache. IFixedCacheStub <NoBuffSocketStub> stub = ChannelConst.NoBuffAsyncStubPool.Rent(); if (stub == null) { _tracing.Warn("Cannot rent a socket async event args cache."); return(-2); } stub.Tag = this; SocketAsyncEventArgs args = stub.Cache.Target; args.SetBuffer(data, 0, data.Length); args.UserToken = stub; bool result = _socket.SendAsync(args); //同步发送完成 if (!result) { //注意,在这里如果是同步完成的,根据MSDN的解释,将不会触发Completed事件 sendCount = args.BytesTransferred; ChannelConst.NoBuffAsyncStubPool.Giveback(stub); } return(sendCount); } catch (System.Exception ex) { _tracing.Error(ex, null); return(sendCount); } }
public static void Build(string[] dlls) { CompilerParameters opt = new CompilerParameters(new string[] { "System.dll", "IICCommonLibrary.dll" }); if (dlls != null) { foreach (var dll in dlls) { opt.ReferencedAssemblies.Add(dll); } } opt.GenerateExecutable = false; opt.TreatWarningsAsErrors = true; opt.IncludeDebugInformation = true; opt.GenerateInMemory = true; CodeDomProvider provider = CodeDomProvider.CreateProvider("cs"); StringWriter sw = new StringWriter(); provider.GenerateCodeFromCompileUnit(CompileUnit, sw, null); string output = sw.ToString(); _tracing.Info(output); sw.Close(); CompilerResults results = provider.CompileAssemblyFromDom(opt, CompileUnit); OutputResults(results); if (results.NativeCompilerReturnValue != 0) { _tracing.Warn("Compilation failed."); throw new ApplicationException("Compilation failed."); } else { _tracing.Info("completed successfully."); } Type typeMethodHelper = results.CompiledAssembly .GetType("Imps.Generics.DynamicTypes.TransparentMethodHelper"); foreach (var pair in dict) { RpcGetArgsDelegate getArgs; MethodInfo mi = typeMethodHelper.GetMethod(pair.Key); getArgs = (RpcGetArgsDelegate)RpcGetArgsDelegate.CreateDelegate( typeof(RpcGetArgsDelegate), mi); pair.Value.GetArgs = getArgs; } }
/// <summary> /// 租借 /// </summary> /// <returns>返回租借后的对象</returns> public SocketAsyncEventArgs Rent() { if (!_args.IsEmpty) { SocketAsyncEventArgs args; if (_args.TryDequeue(out args)) { return(args); } _tracing.Warn("无法租借SocketAsyncEventArgs, 因为尝试出队列的动作没有成功执行。"); } return(null); }
void Completed(object sender, SocketAsyncEventArgs e) { IFixedCacheStub <SocketBuffStub> stub; switch (e.LastOperation) { //send complated event. case SocketAsyncOperation.Send: #region Send Completed. stub = (IFixedCacheStub <SocketBuffStub>)e.UserToken; TcpTransportChannel channel = (TcpTransportChannel)stub.Tag; if (e.SocketError != SocketError.Success && channel.IsConnected) { _tracing.Warn( string.Format( "The target channel SendAsync status has incorrectly, so the framework decided to disconnect it.\r\nL: {0}\r\nR: {1}\r\nSocket-Error: {2}\r\nBytesTransferred: {3}\r\n", channel.LocalEndPoint, channel.RemoteEndPoint, e.SocketError, e.BytesTransferred)); //giveback it at first. ChannelConst.BuffAsyncStubPool.Giveback(stub); channel.Disconnect(); } #endregion break; //send complated event. case SocketAsyncOperation.Receive: #region Recv Completed. stub = (IFixedCacheStub <SocketBuffStub>)e.UserToken; TcpAsynDataRecevier recevier = (TcpAsynDataRecevier)stub.Tag; try { recevier.ProcessReceive(stub); } catch (System.Exception ex) { _tracing.Error(ex, null); } #endregion break; } }
/// <summary> /// 收集目标KAE应用程序集内部的所有消息处理器 /// </summary> /// <returns>返回消息处理器可以处理的消息标示集合</returns> /// <exception cref="DuplicatedProcessorException">具有多个能处理相同MessageIdentity的KAE处理器</exception> /// <exception cref="NotSupportedException">不支持的Protocol Type</exception> protected virtual IDictionary <MessageIdentity, MetadataKAEProcessor> CollectAbilityProcessors() { IDictionary <MessageIdentity, MetadataKAEProcessor> dic = new Dictionary <MessageIdentity, MetadataKAEProcessor>(new MessageIdentityComparer()); Type[] types = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(_structure.GetSectionField <string>(0x00, "ApplicationMainFileName")))).GetTypes(); foreach (Type type in types) { try { if (type.GetTypeInfo().IsAbstract) { continue; } if (!type.GetTypeInfo().IsSubclassOf(typeof(MetadataKAEProcessor))) { continue; } KAEProcessorPropertiesAttribute[] attributes = (KAEProcessorPropertiesAttribute[])type.GetTypeInfo().GetCustomAttributes(typeof(KAEProcessorPropertiesAttribute), true); if (attributes.Length == 0) { _tracing.Warn("#Found a KAE processor, type: {0}. BUT there wasn't any KAEProcessorPropertiesAttribute can be find.", type.Name); continue; } MessageIdentity identity = new MessageIdentity { ProtocolId = attributes[0].ProtocolId, ServiceId = attributes[0].ServiceId, DetailsId = attributes[0].DetailsId }; if (dic.ContainsKey(identity)) { throw new DuplicatedProcessorException("#Duplicated KAE processor which it has same ability to handle a type of message. #MessageIdentity: " + identity); } dic.Add(identity, (MetadataKAEProcessor)Activator.CreateInstance(type, this)); } catch (Exception ex) { _tracing.Error(ex); } } return(dic); }
//thread timer's callback function. private void Callback(object state) { if (!_enable) { return; } if (!CheckCommunication()) { _tracing.Warn("#Health check failed with {0} remote ip endpoint.", _iep); return; } //active event & close currently connection. try { _enable = false; if (_timer != null) { _timer.Dispose(); } SucceedHandler(); } catch (System.Exception ex) { _tracing.Error(ex, null); } }
public static TInterface CreateInterface <TInterface>(string ip) where TInterface : class { object obj; Type tInterface = typeof(TInterface); if (dict.TryGetValue(tInterface, out obj)) { return(obj as TInterface); } MethodInfo[] misInterface = tInterface.GetMethods(BindingFlags.Public | BindingFlags.Instance); List <MethodInfo> misInterfaceList = new List <MethodInfo>(); foreach (var item in misInterface) { if (item.IsSpecialName == false) { misInterfaceList.Add(item); } } CodeCompileUnit CompileUnit = new CodeCompileUnit(); CompileUnit.ReferencedAssemblies.Add(typeof(TInterface).Assembly.ManifestModule.ToString()); CodeNamespace aName = new CodeNamespace("Imps.Generics.DynamicTypes"); CompileUnit.Namespaces.Add(aName); aName.Imports.Add(new CodeNamespaceImport("System")); aName.Imports.Add(new CodeNamespaceImport("Imps.Services.CommonV4")); string className = string.Format("{0}_Proxy", tInterface.Name); CodeTypeDeclaration proxy = new CodeTypeDeclaration(className); aName.Types.Add(proxy); proxy.BaseTypes.Add(typeof(TInterface)); CodeMemberField field_ip = new CodeMemberField(typeof(string), "_ip"); proxy.Members.Add(field_ip); CodeConstructor con = new CodeConstructor(); con.Attributes = MemberAttributes.Public; CodeFieldReferenceExpression field_ip_ref = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_ip"); con.Statements.Add(new CodeAssignStatement(field_ip_ref, new CodePrimitiveExpression(ip))); proxy.Members.Add(con); foreach (var item in misInterfaceList) { CreateMethod(aName, proxy, item, typeof(TInterface)); } CompilerParameters opt = new CompilerParameters(new string[] { "System.dll", "IICCommonLibrary.dll" }); opt.GenerateExecutable = false; opt.TreatWarningsAsErrors = true; opt.IncludeDebugInformation = true; opt.GenerateInMemory = true; CompilerResults results; CodeDomProvider provider = CodeDomProvider.CreateProvider("cs"); StringWriter sw = new StringWriter(); provider.GenerateCodeFromCompileUnit(CompileUnit, sw, null); string output = sw.ToString(); _tracing.Info(output); sw.Close(); results = provider.CompileAssemblyFromDom(opt, CompileUnit); OutputResults(results); if (results.NativeCompilerReturnValue != 0) { _tracing.Warn("Compilation failed."); throw new ApplicationException("Compilation failed."); } else { _tracing.Info("completed successfully."); } obj = results.CompiledAssembly .CreateInstance(string.Format("{0}.{1}", aName.Name, proxy.Name)); dict[tInterface] = obj; return(obj as TInterface); }