├── .gitattributes ├── .gitignore ├── .nuget ├── NuGet.Config ├── NuGet.exe ├── NuGet.md └── NuGet.targets ├── LICENSE ├── README.md ├── Redola ├── Redola.ActorModel │ ├── Actor │ │ ├── Actor.cs │ │ ├── Center │ │ │ └── CenterActor.cs │ │ ├── Channel │ │ │ ├── ActorChannelFactory.cs │ │ │ ├── ActorChannelManager.cs │ │ │ ├── ActorConnectorChannel.cs │ │ │ ├── ActorConnectorReconnectableChannel.cs │ │ │ ├── ActorListenerChannel.cs │ │ │ ├── ActorSessionChannel.cs │ │ │ ├── Configuration │ │ │ │ └── ActorChannelConfiguration.cs │ │ │ ├── EventArgs │ │ │ │ ├── ActorChannelConnectedEventArgs.cs │ │ │ │ ├── ActorChannelDataReceivedEventArgs.cs │ │ │ │ ├── ActorChannelDisconnectedEventArgs.cs │ │ │ │ ├── ActorChannelSessionDataReceivedEventArgs.cs │ │ │ │ └── ActorChannelSessionHandshakedEventArgs.cs │ │ │ ├── IActorChannel.cs │ │ │ └── Transport │ │ │ │ ├── ActorTransportConnector.cs │ │ │ │ ├── ActorTransportListener.cs │ │ │ │ ├── ActorTransportReconnectableConnector.cs │ │ │ │ ├── ActorTransportSession.cs │ │ │ │ ├── Configuration │ │ │ │ └── ActorTransportConfiguration.cs │ │ │ │ └── EventArgs │ │ │ │ ├── ActorTransportConnectedEventArgs.cs │ │ │ │ ├── ActorTransportDataReceivedEventArgs.cs │ │ │ │ ├── ActorTransportDisconnectedEventArgs.cs │ │ │ │ ├── ActorTransportSessionConnectedEventArgs.cs │ │ │ │ ├── ActorTransportSessionDataReceivedEventArgs.cs │ │ │ │ └── ActorTransportSessionDisconnectedEventArgs.cs │ │ ├── Configuration │ │ │ ├── ActorConfiguration.cs │ │ │ ├── ByAppConfig │ │ │ │ ├── AppConfigActorConfiguration.cs │ │ │ │ └── AppConfigActorSettingItems.cs │ │ │ └── ByLocalXmlFile │ │ │ │ ├── LocalXmlFileActorConfiguration.cs │ │ │ │ └── XmlActorConfiguration.cs │ │ ├── Directory │ │ │ ├── CenterActorDirectory │ │ │ │ ├── CenterActorDirectory.cs │ │ │ │ └── Configuration │ │ │ │ │ ├── ByAppConfig │ │ │ │ │ ├── AppConfigCenterActorDirectoryConfiguration.cs │ │ │ │ │ └── AppConfigCenterActorDirectorySettingItems.cs │ │ │ │ │ ├── ByLocalXmlFile │ │ │ │ │ ├── LocalXmlFileCenterActorDirectoryConfiguration.cs │ │ │ │ │ └── XmlCenterActorDirectoryConfiguration.cs │ │ │ │ │ └── CenterActorDirectoryConfiguration.cs │ │ │ ├── EventArgs │ │ │ │ └── ActorsChangedEventArgs.cs │ │ │ └── IActorDirectory.cs │ │ ├── EventArgs │ │ │ ├── ActorConnectedEventArgs.cs │ │ │ ├── ActorDataReceivedEventArgs.cs │ │ │ └── ActorDisconnectedEventArgs.cs │ │ ├── Exception │ │ │ └── ActorNotFoundException.cs │ │ └── Identity │ │ │ ├── ActorIdentity.cs │ │ │ ├── ActorIdentityCollection.cs │ │ │ └── ActorIdentityLookup.cs │ ├── Extensions │ │ └── ConcurrentDictionaryExtensions.cs │ ├── Framing │ │ ├── BinaryFrame.cs │ │ ├── Builder │ │ │ ├── ActorFrameBuilder.cs │ │ │ ├── ActorFrameException.cs │ │ │ ├── Encoding │ │ │ │ ├── IActorControlFrameDataDecoder.cs │ │ │ │ ├── IActorControlFrameDataEncoder.cs │ │ │ │ ├── XmlActorControlFrameDataDecoder.cs │ │ │ │ └── XmlActorControlFrameDataEncoder.cs │ │ │ └── IActorFrameBuilder.cs │ │ ├── ChangeFrame.cs │ │ ├── ControlFrame.cs │ │ ├── DataFrame.cs │ │ ├── Frame.cs │ │ ├── Header │ │ │ ├── ActorFrameHeader.cs │ │ │ └── OpCode.cs │ │ ├── HelloFrame.cs │ │ ├── HereFrame.cs │ │ ├── PingFrame.cs │ │ ├── PongFrame.cs │ │ ├── WelcomeFrame.cs │ │ └── WhereFrame.cs │ ├── KeepAlive │ │ └── KeepAliveTracker.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.ActorModel.csproj │ ├── Serialization │ │ ├── Compression │ │ │ └── GZipCompression.cs │ │ ├── IMessageDecoder.cs │ │ ├── IMessageEncoder.cs │ │ └── Xml │ │ │ ├── XmlConvert.cs │ │ │ ├── XmlMessageDecoder.cs │ │ │ └── XmlMessageEncoder.cs │ └── packages.config ├── Redola.Rpc.DynamicProxy.CastleIntegration │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.DynamicProxy.CastleIntegration.csproj │ ├── ServiceProxyGenerator.cs │ ├── ServiceProxyInterceptor.cs │ └── packages.config ├── Redola.Rpc.ServiceDiscovery.ConsulIntegration │ ├── Actor │ │ ├── ConsulActorRegistry.cs │ │ └── ConsulActorRegistryEntry.cs │ ├── ConsulActorDirectory.cs │ ├── ConsulServiceDirectory.cs │ ├── ConsulServiceDiscovery.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.ServiceDiscovery.ConsulIntegration.csproj │ ├── Service │ │ ├── ConsulServiceRegistry.cs │ │ └── ConsulServiceRegistryEntry.cs │ └── packages.config ├── Redola.Rpc.ServiceDiscovery.XmlIntegration │ ├── Actor │ │ ├── LocalXmlFileActorRegistry.cs │ │ ├── XmlActorRegistry.cs │ │ └── XmlActorRegistryEntry.cs │ ├── LocalXmlFileActorDirectory.cs │ ├── LocalXmlFileServiceDirectory.cs │ ├── LocalXmlFileServiceDiscovery.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.ServiceDiscovery.XmlIntegration.csproj │ ├── Serialization │ │ └── XmlConvert.cs │ ├── Service │ │ ├── LocalXmlFileServiceRegistry.cs │ │ ├── XmlServiceRegistry.cs │ │ └── XmlServiceRegistryEntry.cs │ └── packages.config ├── Redola.Rpc │ ├── Messaging │ │ ├── Encoding │ │ │ ├── ActorMessage │ │ │ │ ├── ActorMessageDecoder.cs │ │ │ │ ├── ActorMessageEncoder.cs │ │ │ │ ├── IActorMessageDecoder.cs │ │ │ │ └── IActorMessageEncoder.cs │ │ │ ├── Compression │ │ │ │ └── GZipCompression.cs │ │ │ ├── IObjectDecoder.cs │ │ │ ├── IObjectEncoder.cs │ │ │ └── Protobuf │ │ │ │ ├── ProtocolBuffersConvert.cs │ │ │ │ ├── ProtocolBuffersObjectDecoder.cs │ │ │ │ └── ProtocolBuffersObjectEncoder.cs │ │ └── Envelope │ │ │ ├── ActorEndpoint.cs │ │ │ ├── ActorMessageEnvelope.cs │ │ │ ├── ActorMessageEnvelope.proto │ │ │ ├── ActorMessageEnvelopeExtensions.cs │ │ │ └── ActorMessageEnvelopeGeneric.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RateLimiting │ │ ├── CountableRateLimiter.cs │ │ └── IRateLimiter.cs │ ├── Redola.Rpc.csproj │ ├── Redola.Rpc.nuspec │ ├── RouteActor │ │ ├── ActorSender.cs │ │ ├── Blocking │ │ │ ├── BlockingActorMessageHandlerBase.cs │ │ │ ├── BlockingCallbackHolder.cs │ │ │ ├── BlockingRouteActor.cs │ │ │ └── IBlockingActorMessageHandler.cs │ │ ├── IActorMessageHandler.cs │ │ ├── IRouteActorMessageHandler.cs │ │ ├── RouteActor.cs │ │ ├── RouteActorMessageHandlerBase.cs │ │ └── Strategy │ │ │ └── MessageHandleStrategy.cs │ ├── Rpc │ │ ├── Actor │ │ │ ├── RpcActor.cs │ │ │ └── RpcHandler.cs │ │ ├── Client │ │ │ ├── RpcClient.cs │ │ │ ├── ServiceProxy │ │ │ │ └── IServiceProxyGenerator.cs │ │ │ └── ServiceResolver │ │ │ │ ├── IServiceResolver.cs │ │ │ │ ├── LoadBalancing │ │ │ │ ├── IServiceLoadBalancingStrategy.cs │ │ │ │ └── RandomServiceLoadBalancingStrategy.cs │ │ │ │ ├── Retrieval │ │ │ │ ├── IServiceRetriever.cs │ │ │ │ └── ServiceRetriever.cs │ │ │ │ └── ServiceResolver.cs │ │ ├── Discovery │ │ │ ├── IServiceDirectory.cs │ │ │ ├── IServiceDiscovery.cs │ │ │ └── ServiceActor.cs │ │ ├── Message │ │ │ ├── Contracts │ │ │ │ ├── ReceiveMessageContract.cs │ │ │ │ ├── RequestResponseMessageContract.cs │ │ │ │ └── RpcMessageContract.cs │ │ │ ├── InvokeMethodMessage.cs │ │ │ ├── InvokeMethodRequest.cs │ │ │ └── InvokeMethodResponse.cs │ │ ├── Method │ │ │ ├── Argument │ │ │ │ ├── Encoding │ │ │ │ │ ├── IMethodArgumentDecoder.cs │ │ │ │ │ ├── IMethodArgumentEncoder.cs │ │ │ │ │ ├── MethodArgumentDecoder.cs │ │ │ │ │ └── MethodArgumentEncoder.cs │ │ │ │ └── SerializableMethodArgument.cs │ │ │ ├── Extractor │ │ │ │ ├── IMethodLocatorExtractor.cs │ │ │ │ └── MethodLocatorExtractor.cs │ │ │ ├── Route │ │ │ │ ├── MethodRoute.cs │ │ │ │ ├── MethodRouteBuilder.cs │ │ │ │ ├── MethodRouteCache.cs │ │ │ │ └── MethodRouteResolver.cs │ │ │ └── RpcMethodFixture.cs │ │ ├── RpcNode.cs │ │ └── Server │ │ │ ├── Catalog │ │ │ ├── IServiceCatalogProvider.cs │ │ │ ├── ServiceCatalogProvider.cs │ │ │ └── ServiceEntry.cs │ │ │ └── RpcServer.cs │ └── packages.config ├── Redola.sln └── SolutionVersion.cs ├── Tests ├── Redola.Rpc.TestActorCenter │ ├── App.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestActorCenter.csproj │ └── packages.config ├── Redola.Rpc.TestActorClient │ ├── App.config │ ├── CalcClient.cs │ ├── HelloClient.cs │ ├── OrderClient.cs │ ├── OrderEventService.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestActorClient.csproj │ └── packages.config ├── Redola.Rpc.TestActorServer │ ├── App.config │ ├── CalcService.cs │ ├── HelloService.cs │ ├── OrderEventClient.cs │ ├── OrderService.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestActorServer.csproj │ └── packages.config ├── Redola.Rpc.TestContracts │ ├── Calc.cs │ ├── Calc.proto │ ├── Hello.cs │ ├── Hello.proto │ ├── Order.cs │ ├── Order.proto │ ├── OrderEvent.cs │ ├── OrderEvent.proto │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestContracts.csproj │ └── packages.config ├── Redola.Rpc.TestHttpRelay.XmlIntegration │ ├── App.config │ ├── Modules │ │ ├── TestContainer.cs │ │ └── TestModule.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestHttpRelay.XmlIntegration.csproj │ ├── XmlConfiguration │ │ ├── ActorRegistry.xml │ │ ├── LocalActor.xml │ │ └── ServiceRegistry.xml │ └── packages.config ├── Redola.Rpc.TestRpcClient.ConsulIntegration │ ├── App.config │ ├── OrderEventService.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestRpcClient.ConsulIntegration.csproj │ ├── XmlConfiguration │ │ └── LocalActor.xml │ └── packages.config ├── Redola.Rpc.TestRpcClient.XmlIntegration │ ├── App.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestRpcClient.XmlIntegration.csproj │ ├── XmlConfiguration │ │ ├── ActorRegistry.xml │ │ ├── LocalActor.xml │ │ └── ServiceRegistry.xml │ └── packages.config ├── Redola.Rpc.TestRpcServer.ConsulIntegration │ ├── App.config │ ├── CalcService.cs │ ├── HelloService.cs │ ├── OrderService.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestRpcServer.ConsulIntegration.csproj │ ├── XmlConfiguration │ │ └── LocalActor.xml │ └── packages.config └── Redola.Rpc.TestRpcServer.XmlIntegration │ ├── App.config │ ├── CalcService.cs │ ├── HelloService.cs │ ├── OrderService.cs │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Redola.Rpc.TestRpcServer.XmlIntegration.csproj │ ├── XmlConfiguration │ ├── ActorRegistry.xml │ ├── LocalActor.xml │ └── ServiceRegistry.xml │ └── packages.config └── tools ├── codegen └── protobuf │ ├── dotnet │ ├── Licence.txt │ ├── common.xslt │ ├── csharp.xslt │ ├── descriptor.proto │ ├── protobuf-net.dll │ ├── protobuf-net.xml │ ├── protoc-license.txt │ ├── protogen.exe │ ├── protogen.exe.config │ ├── vb.xslt │ └── xml.xslt │ └── google │ ├── protoc.exe │ └── readme.txt ├── protobuf-codegen-csharp.bat ├── protobuf-codegen-java.bat └── protobuf-codegen-python.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaochundong/Redola/329de3273a53535fe96d9e920aae269c9c483cf6/.nuget/NuGet.exe -------------------------------------------------------------------------------- /.nuget/NuGet.md: -------------------------------------------------------------------------------- 1 | Commands 2 | ------------ 3 | nuget setApiKey xxx-xxx-xxxx-xxxx -Source https://www.nuget.org/api/v2/package 4 | 5 | nuget push .\packages\Redola.Rpc.1.0.0.0.nupkg -Source https://www.nuget.org/api/v2/package 6 | nuget pack ..\Redola\Redola.Rpc\Redola.Rpc.csproj -IncludeReferencedProjects -Symbols -Build -Prop Configuration=Release -OutputDirectory ".\packages" 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015-2017 Dennis Gao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redola 2 | Redola is a lightweight C# based RPC framework. 3 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Configuration/ActorChannelConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Redola.ActorModel.Framing; 3 | using Redola.ActorModel.Serialization; 4 | 5 | namespace Redola.ActorModel 6 | { 7 | public class ActorChannelConfiguration 8 | { 9 | private IActorFrameBuilder _frameBuilder; 10 | 11 | public ActorChannelConfiguration() 12 | { 13 | var messageEncoder = new XmlMessageEncoder(); 14 | var messageDecoder = new XmlMessageDecoder(); 15 | var controlFrameDataEncoder = new XmlActorControlFrameDataEncoder(messageEncoder); 16 | var controlFrameDataDecoder = new XmlActorControlFrameDataDecoder(messageDecoder); 17 | _frameBuilder = new ActorFrameBuilder(controlFrameDataEncoder, controlFrameDataDecoder); 18 | 19 | this.KeepAliveInterval = TimeSpan.FromSeconds(30); 20 | this.KeepAliveTimeout = TimeSpan.FromSeconds(10); 21 | this.KeepAliveEnabled = true; 22 | 23 | this.TransportConfiguration = new ActorTransportConfiguration(); 24 | } 25 | 26 | public IActorFrameBuilder FrameBuilder { get { return _frameBuilder; } } 27 | public TimeSpan KeepAliveInterval { get; set; } 28 | public TimeSpan KeepAliveTimeout { get; set; } 29 | public bool KeepAliveEnabled { get; set; } 30 | 31 | public ActorTransportConfiguration TransportConfiguration { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/EventArgs/ActorChannelConnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorChannelConnectedEventArgs : EventArgs 6 | { 7 | public ActorChannelConnectedEventArgs(string channelIdentifier, ActorIdentity remoteActor) 8 | { 9 | if (string.IsNullOrEmpty(channelIdentifier)) 10 | throw new ArgumentNullException("channelIdentifier"); 11 | if (remoteActor == null) 12 | throw new ArgumentNullException("remoteActor"); 13 | 14 | this.ChannelIdentifier = channelIdentifier; 15 | this.RemoteActor = remoteActor; 16 | } 17 | 18 | public string ChannelIdentifier { get; private set; } 19 | public ActorIdentity RemoteActor { get; private set; } 20 | 21 | public override string ToString() 22 | { 23 | return string.Format("ChannelIdentifier[{0}], RemoteActor[{1}]", ChannelIdentifier, RemoteActor); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/EventArgs/ActorChannelDataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorChannelDataReceivedEventArgs : EventArgs 6 | { 7 | public ActorChannelDataReceivedEventArgs(string channelIdentifier, ActorIdentity remoteActor, byte[] data) 8 | : this(channelIdentifier, remoteActor, data, 0, data.Length) 9 | { 10 | } 11 | 12 | public ActorChannelDataReceivedEventArgs(string channelIdentifier, ActorIdentity remoteActor, byte[] data, int dataOffset, int dataLength) 13 | { 14 | ChannelIdentifier = channelIdentifier; 15 | RemoteActor = remoteActor; 16 | 17 | Data = data; 18 | DataOffset = dataOffset; 19 | DataLength = dataLength; 20 | } 21 | 22 | public string ChannelIdentifier { get; private set; } 23 | public ActorIdentity RemoteActor { get; private set; } 24 | 25 | public byte[] Data { get; private set; } 26 | public int DataOffset { get; private set; } 27 | public int DataLength { get; private set; } 28 | 29 | public override string ToString() 30 | { 31 | return string.Format("ChannelIdentifier[{0}], RemoteActor[{1}]", ChannelIdentifier, RemoteActor); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/EventArgs/ActorChannelDisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorChannelDisconnectedEventArgs : EventArgs 6 | { 7 | public ActorChannelDisconnectedEventArgs(string channelIdentifier, ActorIdentity remoteActor) 8 | { 9 | if (string.IsNullOrEmpty(channelIdentifier)) 10 | throw new ArgumentNullException("channelIdentifier"); 11 | if (remoteActor == null) 12 | throw new ArgumentNullException("remoteActor"); 13 | 14 | this.ChannelIdentifier = channelIdentifier; 15 | this.RemoteActor = remoteActor; 16 | } 17 | 18 | public string ChannelIdentifier { get; private set; } 19 | public ActorIdentity RemoteActor { get; private set; } 20 | 21 | public override string ToString() 22 | { 23 | return string.Format("ChannelIdentifier[{0}], RemoteActor[{1}]", ChannelIdentifier, RemoteActor); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/EventArgs/ActorChannelSessionDataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorChannelSessionDataReceivedEventArgs : EventArgs 6 | { 7 | public ActorChannelSessionDataReceivedEventArgs( 8 | ActorSessionChannel session, 9 | ActorIdentity remoteActor, 10 | byte[] data) 11 | : this(session, remoteActor, data, 0, data.Length) 12 | { 13 | } 14 | 15 | public ActorChannelSessionDataReceivedEventArgs( 16 | ActorSessionChannel session, 17 | ActorIdentity remoteActor, 18 | byte[] data, int dataOffset, int dataLength) 19 | { 20 | if (session == null) 21 | throw new ArgumentNullException("session"); 22 | if (remoteActor == null) 23 | throw new ArgumentNullException("remoteActor"); 24 | this.Session = session; 25 | this.RemoteActor = remoteActor; 26 | 27 | this.Data = data; 28 | this.DataOffset = dataOffset; 29 | this.DataLength = dataLength; 30 | } 31 | 32 | public string SessionKey { get { return this.Session.SessionKey; } } 33 | public ActorSessionChannel Session { get; private set; } 34 | public ActorIdentity RemoteActor { get; private set; } 35 | 36 | public byte[] Data { get; private set; } 37 | public int DataOffset { get; private set; } 38 | public int DataLength { get; private set; } 39 | 40 | public override string ToString() 41 | { 42 | return SessionKey; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/EventArgs/ActorChannelSessionHandshakedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorChannelSessionHandshakedEventArgs : EventArgs 6 | { 7 | public ActorChannelSessionHandshakedEventArgs( 8 | ActorSessionChannel session, 9 | ActorIdentity remoteActor) 10 | { 11 | if (session == null) 12 | throw new ArgumentNullException("session"); 13 | if (remoteActor == null) 14 | throw new ArgumentNullException("remoteActor"); 15 | this.Session = session; 16 | this.RemoteActor = remoteActor; 17 | } 18 | 19 | public string SessionKey { get { return this.Session.SessionKey; } } 20 | public ActorSessionChannel Session { get; private set; } 21 | public ActorIdentity RemoteActor { get; private set; } 22 | 23 | public override string ToString() 24 | { 25 | return SessionKey; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/IActorChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public interface IActorChannel 6 | { 7 | string Identifier { get; } 8 | ActorIdentity LocalActor { get; } 9 | ActorIdentity RemoteActor { get; } 10 | 11 | bool Active { get; } 12 | void Open(); 13 | void Close(); 14 | 15 | event EventHandler ChannelConnected; 16 | event EventHandler ChannelDisconnected; 17 | event EventHandler ChannelDataReceived; 18 | 19 | void Send(string identifier, byte[] data); 20 | void Send(string identifier, byte[] data, int offset, int count); 21 | void BeginSend(string identifier, byte[] data); 22 | void BeginSend(string identifier, byte[] data, int offset, int count); 23 | 24 | IAsyncResult BeginSend(string identifier, byte[] data, AsyncCallback callback, object state); 25 | IAsyncResult BeginSend(string identifier, byte[] data, int offset, int count, AsyncCallback callback, object state); 26 | void EndSend(string identifier, IAsyncResult asyncResult); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/ActorTransportReconnectableConnector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Threading; 4 | using Cowboy.Sockets; 5 | using Logrila.Logging; 6 | 7 | namespace Redola.ActorModel 8 | { 9 | public class ActorTransportReconnectableConnector : ActorTransportConnector 10 | { 11 | private ILog _log = Logger.Get(); 12 | private System.Threading.Timer _retryTimer = null; 13 | private readonly object _retryLock = new object(); 14 | 15 | public ActorTransportReconnectableConnector(IPEndPoint connectToEndPoint, ActorTransportConfiguration transportConfiguration) 16 | : base(connectToEndPoint, transportConfiguration) 17 | { 18 | this.RetryPeriod = TimeSpan.FromSeconds(15); 19 | } 20 | 21 | public TimeSpan RetryPeriod { get; private set; } 22 | 23 | protected override void OnDisconnect() 24 | { 25 | base.OnDisconnect(); 26 | CloseRetryTimer(); 27 | } 28 | 29 | protected override void OnServerConnected(object sender, TcpServerConnectedEventArgs e) 30 | { 31 | base.OnServerConnected(sender, e); 32 | CloseRetryTimer(); 33 | } 34 | 35 | protected override void OnServerDisconnected(object sender, TcpServerDisconnectedEventArgs e) 36 | { 37 | base.OnServerDisconnected(sender, e); 38 | SetupRetryTimer(); 39 | } 40 | 41 | private void SetupRetryTimer() 42 | { 43 | lock (_retryLock) 44 | { 45 | _log.DebugFormat(string.Format("SetupRetryTimer, setup retry timer [{0}] when connect to [{1}].", 46 | this.RetryPeriod, this.ConnectToEndPoint)); 47 | 48 | if (_retryTimer == null) 49 | { 50 | _retryTimer = new System.Threading.Timer( 51 | (s) => 52 | { 53 | try 54 | { 55 | Connect(); 56 | } 57 | catch (Exception ex) 58 | { 59 | _log.Error(ex.Message, ex); 60 | } 61 | }, 62 | null, this.RetryPeriod, this.RetryPeriod); 63 | } 64 | } 65 | } 66 | 67 | private void CloseRetryTimer() 68 | { 69 | lock (_retryLock) 70 | { 71 | _log.DebugFormat(string.Format("CloseRetryTimer, close retry timer [{0}] to connect [{1}].", 72 | this.RetryPeriod, this.ConnectToEndPoint)); 73 | 74 | if (_retryTimer != null) 75 | { 76 | _retryTimer.Change(Timeout.Infinite, Timeout.Infinite); 77 | _retryTimer.Dispose(); 78 | _retryTimer = null; 79 | } 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/ActorTransportSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Net.Sockets; 5 | using Cowboy.Sockets; 6 | 7 | namespace Redola.ActorModel 8 | { 9 | public class ActorTransportSession 10 | { 11 | private TcpSocketSession _session; 12 | 13 | public ActorTransportSession(TcpSocketSession session) 14 | { 15 | if (session == null) 16 | throw new ArgumentNullException("session"); 17 | _session = session; 18 | this.SessionKey = _session.SessionKey; 19 | } 20 | 21 | public string SessionKey { get; private set; } 22 | public DateTime StartTime { get { return _session.StartTime; } } 23 | public bool Active { get { return _session.State == TcpSocketConnectionState.Connected; } } 24 | public IPEndPoint RemoteEndPoint { get { return _session.RemoteEndPoint; } } 25 | public IPEndPoint LocalEndPoint { get { return _session.LocalEndPoint; } } 26 | public Socket Socket { get { return _session.Socket; } } 27 | public Stream Stream { get { return _session.Stream; } } 28 | public TcpSocketServer Server { get { return _session.Server; } } 29 | public TimeSpan ConnectTimeout { get { return _session.ConnectTimeout; } } 30 | 31 | public void Close() 32 | { 33 | if (_session.State != TcpSocketConnectionState.Closed) 34 | { 35 | _session.Close(); 36 | } 37 | } 38 | 39 | public void Send(byte[] data) 40 | { 41 | Send(data, 0, data.Length); 42 | } 43 | 44 | public void Send(byte[] data, int offset, int count) 45 | { 46 | _session.Send(data, offset, count); 47 | } 48 | 49 | public void BeginSend(byte[] data) 50 | { 51 | BeginSend(data, 0, data.Length); 52 | } 53 | 54 | public void BeginSend(byte[] data, int offset, int count) 55 | { 56 | _session.BeginSend(data, offset, count); 57 | } 58 | 59 | public IAsyncResult BeginSend(byte[] data, AsyncCallback callback, object state) 60 | { 61 | return BeginSend(data, 0, data.Length, callback, state); 62 | } 63 | 64 | public IAsyncResult BeginSend(byte[] data, int offset, int count, AsyncCallback callback, object state) 65 | { 66 | return _session.BeginSend(data, offset, count, callback, state); 67 | } 68 | 69 | public void EndSend(IAsyncResult asyncResult) 70 | { 71 | _session.EndSend(asyncResult); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/Configuration/ActorTransportConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | 4 | namespace Redola.ActorModel 5 | { 6 | public class ActorTransportConfiguration 7 | { 8 | public ActorTransportConfiguration() 9 | { 10 | ReceiveBufferSize = 4096; // Specifies the total per-socket buffer space reserved for receives. This is unrelated to the maximum message size or the size of a TCP window. 11 | SendBufferSize = 4096; // Specifies the total per-socket buffer space reserved for sends. This is unrelated to the maximum message size or the size of a TCP window. 12 | ReceiveTimeout = TimeSpan.Zero; // Receive a time-out. This option applies only to synchronous methods; it has no effect on asynchronous methods such as the BeginSend method. 13 | SendTimeout = TimeSpan.Zero; // Send a time-out. This option applies only to synchronous methods; it has no effect on asynchronous methods such as the BeginSend method. 14 | NoDelay = true; // Disables the Nagle algorithm for send coalescing. 15 | LingerState = new LingerOption(false, 0); // The socket will linger for x seconds after Socket.Close is called. 16 | KeepAlive = false; // Use keep-alives. 17 | KeepAliveInterval = TimeSpan.FromSeconds(5);// https://msdn.microsoft.com/en-us/library/system.net.sockets.socketoptionname(v=vs.110).aspx 18 | ReuseAddress = false; // Allows the socket to be bound to an address that is already in use. 19 | 20 | ConnectTimeout = TimeSpan.FromSeconds(10); 21 | } 22 | 23 | public int ReceiveBufferSize { get; set; } 24 | public int SendBufferSize { get; set; } 25 | public TimeSpan ReceiveTimeout { get; set; } 26 | public TimeSpan SendTimeout { get; set; } 27 | public bool NoDelay { get; set; } 28 | public LingerOption LingerState { get; set; } 29 | public bool KeepAlive { get; set; } 30 | public TimeSpan KeepAliveInterval { get; set; } 31 | public bool ReuseAddress { get; set; } 32 | 33 | public TimeSpan ConnectTimeout { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportConnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportConnectedEventArgs : EventArgs 6 | { 7 | public ActorTransportConnectedEventArgs(string sessionKey) 8 | { 9 | if (string.IsNullOrEmpty(sessionKey)) 10 | throw new ArgumentNullException("sessionKey"); 11 | this.SessionKey = sessionKey; 12 | } 13 | 14 | public string SessionKey { get; private set; } 15 | 16 | public override string ToString() 17 | { 18 | return SessionKey; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportDataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportDataReceivedEventArgs : EventArgs 6 | { 7 | public ActorTransportDataReceivedEventArgs(string sessionKey, byte[] data) 8 | : this(sessionKey, data, 0, data.Length) 9 | { 10 | } 11 | 12 | public ActorTransportDataReceivedEventArgs(string sessionKey, byte[] data, int dataOffset, int dataLength) 13 | { 14 | SessionKey = sessionKey; 15 | Data = data; 16 | DataOffset = dataOffset; 17 | DataLength = dataLength; 18 | } 19 | 20 | public string SessionKey { get; private set; } 21 | 22 | public byte[] Data { get; private set; } 23 | public int DataOffset { get; private set; } 24 | public int DataLength { get; private set; } 25 | 26 | public override string ToString() 27 | { 28 | return SessionKey; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportDisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportDisconnectedEventArgs : EventArgs 6 | { 7 | public ActorTransportDisconnectedEventArgs(string sessionKey) 8 | { 9 | if (string.IsNullOrEmpty(sessionKey)) 10 | throw new ArgumentNullException("sessionKey"); 11 | this.SessionKey = sessionKey; 12 | } 13 | 14 | public string SessionKey { get; private set; } 15 | 16 | public override string ToString() 17 | { 18 | return SessionKey; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportSessionConnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportSessionConnectedEventArgs : EventArgs 6 | { 7 | public ActorTransportSessionConnectedEventArgs(ActorTransportSession session) 8 | { 9 | if (session == null) 10 | throw new ArgumentNullException("session"); 11 | this.Session = session; 12 | } 13 | 14 | public string SessionKey { get { return this.Session.SessionKey; } } 15 | public ActorTransportSession Session { get; private set; } 16 | 17 | public override string ToString() 18 | { 19 | return SessionKey; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportSessionDataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportSessionDataReceivedEventArgs : EventArgs 6 | { 7 | public ActorTransportSessionDataReceivedEventArgs(ActorTransportSession session, byte[] data) 8 | : this(session, data, 0, data.Length) 9 | { 10 | } 11 | 12 | public ActorTransportSessionDataReceivedEventArgs(ActorTransportSession session, byte[] data, int dataOffset, int dataLength) 13 | { 14 | if (session == null) 15 | throw new ArgumentNullException("session"); 16 | Session = session; 17 | 18 | Data = data; 19 | DataOffset = dataOffset; 20 | DataLength = dataLength; 21 | } 22 | 23 | public string SessionKey { get { return this.Session.SessionKey; } } 24 | public ActorTransportSession Session { get; private set; } 25 | 26 | public byte[] Data { get; private set; } 27 | public int DataOffset { get; private set; } 28 | public int DataLength { get; private set; } 29 | 30 | public override string ToString() 31 | { 32 | return SessionKey; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Channel/Transport/EventArgs/ActorTransportSessionDisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorTransportSessionDisconnectedEventArgs : EventArgs 6 | { 7 | public ActorTransportSessionDisconnectedEventArgs(ActorTransportSession session) 8 | { 9 | if (session == null) 10 | throw new ArgumentNullException("session"); 11 | this.Session = session; 12 | } 13 | 14 | public string SessionKey { get { return this.Session.SessionKey; } } 15 | public ActorTransportSession Session { get; private set; } 16 | 17 | public override string ToString() 18 | { 19 | return SessionKey; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Configuration/ActorConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel 2 | { 3 | public abstract class ActorConfiguration 4 | { 5 | private ActorIdentity _localActor; 6 | private ActorChannelConfiguration _channelConfiguration; 7 | 8 | public ActorConfiguration() 9 | { 10 | } 11 | 12 | public ActorIdentity LocalActor { get { return _localActor; } } 13 | public ActorChannelConfiguration ChannelConfiguration { get { return _channelConfiguration; } } 14 | 15 | public ActorConfiguration Build() 16 | { 17 | _localActor = BuildLocalActor(); 18 | _channelConfiguration = BuildChannelConfiguration(); 19 | 20 | return this; 21 | } 22 | 23 | protected abstract ActorIdentity BuildLocalActor(); 24 | 25 | protected virtual ActorChannelConfiguration BuildChannelConfiguration() 26 | { 27 | return new ActorChannelConfiguration(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Configuration/ByAppConfig/AppConfigActorSettingItems.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Globalization; 4 | using System.Linq; 5 | 6 | namespace Redola.ActorModel 7 | { 8 | public class AppConfigActorSettingItems 9 | { 10 | public const string ActorTypeKey = @"ActorType"; 11 | public const string ActorNameKey = @"ActorName"; 12 | public const string ActorAddressKey = @"ActorAddress"; 13 | public const string ActorPortKey = @"ActorPort"; 14 | 15 | public const string KeepAliveIntervalKey = @"KeepAliveIntervalByMilliseconds"; 16 | public const string KeepAliveTimeoutKey = @"KeepAliveTimeoutByMilliseconds"; 17 | public const string KeepAliveEnabledKey = @"KeepAliveEnabled"; 18 | 19 | private static AppConfigActorSettingItems _instance = new AppConfigActorSettingItems(); 20 | 21 | public static AppConfigActorSettingItems Singleton() 22 | { 23 | return _instance; 24 | } 25 | 26 | public T GetItem(string itemName) where T : IConvertible 27 | { 28 | if (ConfigurationManager.AppSettings.AllKeys.Contains(itemName)) 29 | { 30 | return (T)Convert.ChangeType( 31 | ConfigurationManager.AppSettings[itemName], 32 | typeof(T), CultureInfo.InvariantCulture); 33 | } 34 | 35 | return default(T); 36 | } 37 | 38 | public bool ContainsItem(string itemName) 39 | { 40 | return ConfigurationManager.AppSettings.AllKeys.Contains(itemName); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Configuration/ByLocalXmlFile/LocalXmlFileActorConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Redola.ActorModel.Serialization; 4 | 5 | namespace Redola.ActorModel 6 | { 7 | public class LocalXmlFileActorConfiguration : ActorConfiguration 8 | { 9 | private string _localXmlFilePath = string.Empty; 10 | private XmlActorConfiguration _configuration; 11 | 12 | public LocalXmlFileActorConfiguration(string localXmlFilePath) 13 | { 14 | if (string.IsNullOrEmpty(localXmlFilePath)) 15 | throw new ArgumentNullException("localXmlFilePath"); 16 | if (!File.Exists(localXmlFilePath)) 17 | throw new FileNotFoundException("Cannot find the xml actor configuration file.", localXmlFilePath); 18 | _localXmlFilePath = localXmlFilePath; 19 | 20 | var fileContent = File.ReadAllText(_localXmlFilePath); 21 | _configuration = XmlConvert.DeserializeObject(fileContent); 22 | } 23 | 24 | public string LocalXmlFilePath 25 | { 26 | get { return _localXmlFilePath; } 27 | } 28 | 29 | protected override ActorIdentity BuildLocalActor() 30 | { 31 | var actorType = _configuration.LocalActor.Type; 32 | var actorName = _configuration.LocalActor.Name; 33 | var actorAddress = _configuration.LocalActor.Address; 34 | var actorPort = _configuration.LocalActor.Port; 35 | if (string.IsNullOrWhiteSpace(actorType)) 36 | throw new InvalidProgramException( 37 | string.Format("Local actor type cannot be empty.")); 38 | if (string.IsNullOrWhiteSpace(actorName)) 39 | throw new InvalidProgramException( 40 | string.Format("Local actor name cannot be empty.")); 41 | if (string.IsNullOrWhiteSpace(actorAddress)) 42 | throw new InvalidProgramException( 43 | string.Format("Local actor address cannot be empty.")); 44 | if (string.IsNullOrWhiteSpace(actorPort)) 45 | throw new InvalidProgramException( 46 | string.Format("Local actor port cannot be empty.")); 47 | 48 | var actor = new ActorIdentity(actorType, actorName); 49 | actor.Address = actorAddress; 50 | actor.Port = actorPort; 51 | 52 | return actor; 53 | } 54 | 55 | public static LocalXmlFileActorConfiguration Load(string localXmlFilePath) 56 | { 57 | var configuration = new LocalXmlFileActorConfiguration(localXmlFilePath); 58 | configuration.Build(); 59 | return configuration; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Configuration/ByLocalXmlFile/XmlActorConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | [XmlType(TypeName = "Configuration")] 6 | public class XmlActorConfiguration 7 | { 8 | [XmlElement(ElementName = "LocalActor")] 9 | public ActorIdentity LocalActor { get; set; } 10 | 11 | public override string ToString() 12 | { 13 | return string.Format("{0}", this.LocalActor); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Directory/CenterActorDirectory/Configuration/ByAppConfig/AppConfigCenterActorDirectorySettingItems.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Globalization; 4 | using System.Linq; 5 | 6 | namespace Redola.ActorModel 7 | { 8 | public class AppConfigCenterActorDirectorySettingItems 9 | { 10 | public const string CenterActorTypeKey = @"CenterActorType"; 11 | public const string CenterActorNameKey = @"CenterActorName"; 12 | public const string CenterActorAddressKey = @"CenterActorAddress"; 13 | public const string CenterActorPortKey = @"CenterActorPort"; 14 | 15 | public const string KeepAliveIntervalKey = @"KeepAliveIntervalByMilliseconds"; 16 | public const string KeepAliveTimeoutKey = @"KeepAliveTimeoutByMilliseconds"; 17 | public const string KeepAliveEnabledKey = @"KeepAliveEnabled"; 18 | 19 | private static AppConfigCenterActorDirectorySettingItems _instance = new AppConfigCenterActorDirectorySettingItems(); 20 | 21 | public static AppConfigCenterActorDirectorySettingItems Singleton() 22 | { 23 | return _instance; 24 | } 25 | 26 | public T GetItem(string itemName) where T : IConvertible 27 | { 28 | if (ConfigurationManager.AppSettings.AllKeys.Contains(itemName)) 29 | { 30 | return (T)Convert.ChangeType( 31 | ConfigurationManager.AppSettings[itemName], 32 | typeof(T), CultureInfo.InvariantCulture); 33 | } 34 | 35 | return default(T); 36 | } 37 | 38 | public bool ContainsItem(string itemName) 39 | { 40 | return ConfigurationManager.AppSettings.AllKeys.Contains(itemName); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Directory/CenterActorDirectory/Configuration/ByLocalXmlFile/XmlCenterActorDirectoryConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Serialization; 3 | 4 | namespace Redola.ActorModel 5 | { 6 | [XmlType(TypeName = "Configuration")] 7 | public class XmlCenterActorDirectoryConfiguration 8 | { 9 | [XmlElement(ElementName = "CenterActor")] 10 | public ActorIdentity CenterActor { get; set; } 11 | 12 | [XmlArray(ElementName = "ActorDirectory")] 13 | public List Directory { get; set; } 14 | 15 | public override string ToString() 16 | { 17 | return string.Format("{0}", this.CenterActor); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Directory/CenterActorDirectory/Configuration/CenterActorDirectoryConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel 2 | { 3 | public abstract class CenterActorDirectoryConfiguration 4 | { 5 | private ActorIdentity _centerActor; 6 | private ActorChannelConfiguration _channelConfiguration; 7 | 8 | public CenterActorDirectoryConfiguration() 9 | { 10 | } 11 | 12 | public ActorIdentity CenterActor { get { return _centerActor; } } 13 | public ActorChannelConfiguration ChannelConfiguration { get { return _channelConfiguration; } } 14 | 15 | public CenterActorDirectoryConfiguration Build() 16 | { 17 | _centerActor = BuildCenterActor(); 18 | _channelConfiguration = BuildChannelConfiguration(); 19 | 20 | return this; 21 | } 22 | 23 | protected abstract ActorIdentity BuildCenterActor(); 24 | 25 | protected virtual ActorChannelConfiguration BuildChannelConfiguration() 26 | { 27 | return new ActorChannelConfiguration(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Directory/EventArgs/ActorsChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.ActorModel 6 | { 7 | public class ActorsChangedEventArgs : EventArgs 8 | { 9 | public ActorsChangedEventArgs(IEnumerable actors) 10 | { 11 | if (actors == null) 12 | throw new ArgumentNullException("actors"); 13 | 14 | this.Actors = actors; 15 | } 16 | 17 | public IEnumerable Actors { get; private set; } 18 | 19 | public override string ToString() 20 | { 21 | return string.Format("ActorCount[{0}]", Actors.Count()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Directory/IActorDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | 5 | namespace Redola.ActorModel 6 | { 7 | public interface IActorDirectory 8 | { 9 | void Open(); 10 | void Close(); 11 | bool Active { get; } 12 | 13 | void Register(ActorIdentity localActor); 14 | void Deregister(ActorIdentity localActor); 15 | 16 | IPEndPoint LookupRemoteActorEndPoint(string actorType, string actorName); 17 | IEnumerable LookupRemoteActorEndPoints(string actorType); 18 | IEnumerable LookupRemoteActors(string actorType); 19 | 20 | event EventHandler ActorsChanged; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/EventArgs/ActorConnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorConnectedEventArgs : EventArgs 6 | { 7 | public ActorConnectedEventArgs(string actorChannelIdentifier, ActorIdentity remoteActor) 8 | { 9 | if (string.IsNullOrEmpty(actorChannelIdentifier)) 10 | throw new ArgumentNullException("actorChannelIdentifier"); 11 | if (remoteActor == null) 12 | throw new ArgumentNullException("remoteActor"); 13 | 14 | this.ActorChannelIdentifier = actorChannelIdentifier; 15 | this.RemoteActor = remoteActor; 16 | } 17 | 18 | public string ActorChannelIdentifier { get; private set; } 19 | public ActorIdentity RemoteActor { get; private set; } 20 | 21 | public override string ToString() 22 | { 23 | return string.Format("ActorChannelIdentifier[{0}], RemoteActor[{1}]", ActorChannelIdentifier, RemoteActor); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/EventArgs/ActorDataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorDataReceivedEventArgs : EventArgs 6 | { 7 | public ActorDataReceivedEventArgs(string actorChannelIdentifier, ActorIdentity remoteActor, byte[] data) 8 | : this(actorChannelIdentifier, remoteActor, data, 0, data.Length) 9 | { 10 | } 11 | 12 | public ActorDataReceivedEventArgs(string actorChannelIdentifier, ActorIdentity remoteActor, byte[] data, int dataOffset, int dataLength) 13 | { 14 | ActorChannelIdentifier = actorChannelIdentifier; 15 | RemoteActor = remoteActor; 16 | 17 | Data = data; 18 | DataOffset = dataOffset; 19 | DataLength = dataLength; 20 | } 21 | 22 | public string ActorChannelIdentifier { get; private set; } 23 | public ActorIdentity RemoteActor { get; private set; } 24 | 25 | public byte[] Data { get; private set; } 26 | public int DataOffset { get; private set; } 27 | public int DataLength { get; private set; } 28 | 29 | public override string ToString() 30 | { 31 | return string.Format("ActorChannelIdentifier[{0}], RemoteActor[{1}]", ActorChannelIdentifier, RemoteActor); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/EventArgs/ActorDisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | public class ActorDisconnectedEventArgs : EventArgs 6 | { 7 | public ActorDisconnectedEventArgs(string actorChannelIdentifier, ActorIdentity remoteActor) 8 | { 9 | if (string.IsNullOrEmpty(actorChannelIdentifier)) 10 | throw new ArgumentNullException("actorChannelIdentifier"); 11 | if (remoteActor == null) 12 | throw new ArgumentNullException("remoteActor"); 13 | 14 | this.ActorChannelIdentifier = actorChannelIdentifier; 15 | this.RemoteActor = remoteActor; 16 | } 17 | 18 | public string ActorChannelIdentifier { get; private set; } 19 | public ActorIdentity RemoteActor { get; private set; } 20 | 21 | public override string ToString() 22 | { 23 | return string.Format("ActorChannelIdentifier[{0}], RemoteActor[{1}]", ActorChannelIdentifier, RemoteActor); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Exception/ActorNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel 4 | { 5 | [Serializable] 6 | public class ActorNotFoundException : Exception 7 | { 8 | public ActorNotFoundException(string message) 9 | : base(message) 10 | { 11 | } 12 | 13 | public ActorNotFoundException(string message, Exception innerException) 14 | : base(message, innerException) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Identity/ActorIdentityCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Serialization; 4 | 5 | namespace Redola.ActorModel 6 | { 7 | [Serializable] 8 | [XmlRoot] 9 | public class ActorIdentityCollection 10 | { 11 | public ActorIdentityCollection() 12 | { 13 | Items = new List(); 14 | } 15 | 16 | [XmlArray] 17 | public List Items { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Actor/Identity/ActorIdentityLookup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | namespace Redola.ActorModel 5 | { 6 | [Serializable] 7 | [XmlRoot] 8 | public class ActorIdentityLookup 9 | { 10 | public ActorIdentityLookup() 11 | { 12 | } 13 | 14 | [XmlElement] 15 | public string Type { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Extensions/ConcurrentDictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace Redola.ActorModel.Extensions 4 | { 5 | public static class ConcurrentDictionaryExtensions 6 | { 7 | public static TValue Add(this ConcurrentDictionary collection, TKey key, TValue @value) 8 | { 9 | TValue result = collection.AddOrUpdate(key, @value, (k, v) => { return @value; }); 10 | return result; 11 | } 12 | 13 | public static TValue Update(this ConcurrentDictionary collection, TKey key, TValue @value) 14 | { 15 | TValue result = collection.AddOrUpdate(key, @value, (k, v) => { return @value; }); 16 | return result; 17 | } 18 | 19 | public static TValue Get(this ConcurrentDictionary collection, TKey key) 20 | { 21 | TValue @value = default(TValue); 22 | collection.TryGetValue(key, out @value); 23 | return @value; 24 | } 25 | 26 | public static TValue Remove(this ConcurrentDictionary collection, TKey key) 27 | { 28 | TValue @value = default(TValue); 29 | collection.TryRemove(key, out @value); 30 | return @value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/ActorFrameException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | [Serializable] 6 | public class ActorFrameException : Exception 7 | { 8 | public ActorFrameException(string message) 9 | : base(message) 10 | { 11 | } 12 | 13 | public ActorFrameException(string message, Exception innerException) 14 | : base(message, innerException) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/Encoding/IActorControlFrameDataDecoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public interface IActorControlFrameDataDecoder 4 | { 5 | T DecodeFrameData(byte[] data, int offset, int count); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/Encoding/IActorControlFrameDataEncoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public interface IActorControlFrameDataEncoder 4 | { 5 | byte[] EncodeFrameData(T frameData); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/Encoding/XmlActorControlFrameDataDecoder.cs: -------------------------------------------------------------------------------- 1 | using Redola.ActorModel.Serialization; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | internal class XmlActorControlFrameDataDecoder : IActorControlFrameDataDecoder 6 | { 7 | private IMessageDecoder _decoder; 8 | 9 | public XmlActorControlFrameDataDecoder(IMessageDecoder decoder) 10 | { 11 | _decoder = decoder; 12 | } 13 | 14 | public T DecodeFrameData(byte[] data, int offset, int count) 15 | { 16 | return _decoder.DecodeMessage(data, offset, count); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/Encoding/XmlActorControlFrameDataEncoder.cs: -------------------------------------------------------------------------------- 1 | using Redola.ActorModel.Serialization; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | internal class XmlActorControlFrameDataEncoder : IActorControlFrameDataEncoder 6 | { 7 | private IMessageEncoder _encoder; 8 | 9 | public XmlActorControlFrameDataEncoder(IMessageEncoder encoder) 10 | { 11 | _encoder = encoder; 12 | } 13 | 14 | public byte[] EncodeFrameData(T frameData) 15 | { 16 | return _encoder.EncodeMessage(frameData); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Builder/IActorFrameBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public interface IActorFrameBuilder 4 | { 5 | IActorControlFrameDataEncoder ControlFrameDataEncoder { get; } 6 | IActorControlFrameDataDecoder ControlFrameDataDecoder { get; } 7 | 8 | byte[] EncodeFrame(HelloFrame frame); 9 | byte[] EncodeFrame(WelcomeFrame frame); 10 | byte[] EncodeFrame(PingFrame frame); 11 | byte[] EncodeFrame(PongFrame frame); 12 | byte[] EncodeFrame(WhereFrame frame); 13 | byte[] EncodeFrame(HereFrame frame); 14 | byte[] EncodeFrame(BinaryFrame frame); 15 | byte[] EncodeFrame(ChangeFrame frame); 16 | 17 | bool TryDecodeFrameHeader(byte[] buffer, int offset, int count, out ActorFrameHeader frameHeader); 18 | void DecodePayload(byte[] buffer, int offset, ActorFrameHeader frameHeader, out byte[] payload, out int payloadOffset, out int payloadCount); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/ChangeFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class ChangeFrame : ControlFrame 6 | { 7 | public ChangeFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public ChangeFrame(byte[] data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public byte[] Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Change; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/ControlFrame.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public abstract class ControlFrame : Frame 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/DataFrame.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public abstract class DataFrame : Frame 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Frame.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public abstract class Frame 4 | { 5 | public abstract OpCode OpCode { get; } 6 | 7 | public override string ToString() 8 | { 9 | return string.Format("OpName[{0}], OpCode[{1}]", OpCode, (byte)OpCode); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Header/ActorFrameHeader.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | public class ActorFrameFixedHeader 4 | { 5 | public bool IsRSV0 { get; set; } 6 | public bool IsRSV1 { get; set; } 7 | public bool IsRSV2 { get; set; } 8 | public bool IsRSV3 { get; set; } 9 | public OpCode OpCode { get; set; } 10 | public bool IsMasked { get; set; } 11 | 12 | public override string ToString() 13 | { 14 | return string.Format("IsRSV0[{0}], IsRSV1[{1}], IsRSV2[{2}], IsRSV3[{3}], OpCode[{4}], IsMasked[{5}]", 15 | IsRSV0, IsRSV1, IsRSV2, IsRSV3, OpCode, IsMasked); 16 | } 17 | } 18 | 19 | public class ActorFrameHeader : ActorFrameFixedHeader 20 | { 21 | public int PayloadLength { get; set; } 22 | public int MaskingKeyOffset { get; set; } 23 | public int Length { get; set; } 24 | 25 | public override string ToString() 26 | { 27 | return string.Format("IsRSV0[{0}], IsRSV1[{1}], IsRSV2[{2}], IsRSV3[{3}], OpCode[{4}], IsMasked[{5}], PayloadLength[{6}], MaskingKeyOffset[{7}], Length[{8}]", 28 | IsRSV0, IsRSV1, IsRSV2, IsRSV3, OpCode, IsMasked, PayloadLength, MaskingKeyOffset, Length); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/Header/OpCode.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.ActorModel.Framing 2 | { 3 | // The opcode denotes the frame type of the Actor frame. 4 | // The opcode is an integer number between 0 and 15, inclusive. 5 | // Opcode Meaning Reference 6 | // 1 Hello Frame 7 | // 2 Welcome Frame 8 | // 3 Ping Frame 9 | // 4 Pong Frame 10 | // 5 Where Frame 11 | // 6 Here Frame 12 | // 7 Binary Frame 13 | // 8 Change Frame 14 | // 9-15 Unassigned 15 | public enum OpCode : byte 16 | { 17 | Hello = 1, 18 | Welcome = 2, 19 | Ping = 3, 20 | Pong = 4, 21 | Where = 5, 22 | Here = 6, 23 | Binary = 7, 24 | Change = 8, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/HelloFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class HelloFrame : ControlFrame 6 | { 7 | public HelloFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public HelloFrame(byte[] data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public byte[] Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Hello; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/HereFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class HereFrame : ControlFrame 6 | { 7 | public HereFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public HereFrame(byte[] data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public byte[] Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Here; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/PingFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class PingFrame : ControlFrame 6 | { 7 | public PingFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public PingFrame(string data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public string Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Ping; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/PongFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class PongFrame : ControlFrame 6 | { 7 | public PongFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public PongFrame(string data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public string Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Pong; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/WelcomeFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class WelcomeFrame : ControlFrame 6 | { 7 | public WelcomeFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public WelcomeFrame(byte[] data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public byte[] Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Welcome; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Framing/WhereFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.ActorModel.Framing 4 | { 5 | public sealed class WhereFrame : ControlFrame 6 | { 7 | public WhereFrame(bool isMasked = false) 8 | { 9 | this.IsMasked = isMasked; 10 | } 11 | 12 | public WhereFrame(byte[] data, bool isMasked = false) 13 | : this(isMasked) 14 | { 15 | this.Data = data; 16 | } 17 | 18 | public byte[] Data { get; private set; } 19 | public bool IsMasked { get; private set; } 20 | 21 | public override OpCode OpCode 22 | { 23 | get { return OpCode.Where; } 24 | } 25 | 26 | public byte[] ToArray(IActorFrameBuilder builder) 27 | { 28 | if (builder == null) 29 | throw new ArgumentNullException("builder"); 30 | return builder.EncodeFrame(this); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.ActorModel")] 5 | [assembly: Guid("05e69e70-97ff-4fff-b106-e423b6f51a00")] 6 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Serialization/Compression/GZipCompression.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | 4 | namespace Redola.ActorModel.Serialization 5 | { 6 | internal static class GZipCompression 7 | { 8 | public static byte[] Compress(byte[] raw) 9 | { 10 | return Compress(raw, 0, raw.Length); 11 | } 12 | 13 | public static byte[] Compress(byte[] raw, int offset, int count) 14 | { 15 | using (var memory = new MemoryStream()) 16 | { 17 | using (var gzip = new GZipStream(memory, CompressionMode.Compress, true)) 18 | { 19 | gzip.Write(raw, offset, count); 20 | } 21 | return memory.ToArray(); 22 | } 23 | } 24 | 25 | public static byte[] Decompress(byte[] gzip) 26 | { 27 | return Decompress(gzip, 0, gzip.Length); 28 | } 29 | 30 | public static byte[] Decompress(byte[] gzip, int offset, int count) 31 | { 32 | using (var input = new MemoryStream(gzip, offset, count)) 33 | using (var stream = new GZipStream(input, CompressionMode.Decompress)) 34 | { 35 | const int size = 1024; 36 | byte[] buffer = new byte[size]; 37 | using (var memory = new MemoryStream()) 38 | { 39 | int readCount = 0; 40 | do 41 | { 42 | readCount = stream.Read(buffer, 0, size); 43 | if (readCount > 0) 44 | { 45 | memory.Write(buffer, 0, readCount); 46 | } 47 | } 48 | while (readCount > 0); 49 | 50 | return memory.ToArray(); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Serialization/IMessageDecoder.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Redola.ActorModel.Serialization 3 | { 4 | internal interface IMessageDecoder 5 | { 6 | T DecodeMessage(byte[] data); 7 | T DecodeMessage(byte[] data, int dataLength); 8 | T DecodeMessage(byte[] data, int dataOffset, int dataLength); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Serialization/IMessageEncoder.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Redola.ActorModel.Serialization 3 | { 4 | internal interface IMessageEncoder 5 | { 6 | byte[] EncodeMessage(object message); 7 | byte[] EncodeMessage(T message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Serialization/Xml/XmlMessageDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Redola.ActorModel.Serialization 5 | { 6 | internal class XmlMessageDecoder : IMessageDecoder 7 | { 8 | public XmlMessageDecoder() 9 | { 10 | this.CompressionEnabled = true; 11 | } 12 | 13 | public bool CompressionEnabled { get; set; } 14 | 15 | public T DecodeMessage(byte[] data) 16 | { 17 | return DecodeMessage(data, data.Length); 18 | } 19 | 20 | public T DecodeMessage(byte[] data, int dataLength) 21 | { 22 | return DecodeMessage(data, 0, dataLength); 23 | } 24 | 25 | public T DecodeMessage(byte[] data, int dataOffset, int dataLength) 26 | { 27 | if (data == null) 28 | { 29 | throw new ArgumentNullException("data", "The data which is to be deserialized cannot be null."); 30 | } 31 | if (dataOffset < 0 || dataOffset > data.Length) 32 | { 33 | throw new ArgumentOutOfRangeException("dataOffset"); 34 | } 35 | if (dataLength < 0 || dataLength > (data.Length - dataOffset)) 36 | { 37 | throw new ArgumentOutOfRangeException("dataLength"); 38 | } 39 | 40 | if (CompressionEnabled) 41 | { 42 | string xml = Encoding.UTF8.GetString(GZipCompression.Decompress(data, dataOffset, dataLength)); 43 | return XmlConvert.DeserializeObject(xml); 44 | } 45 | else 46 | { 47 | string xml = Encoding.UTF8.GetString(data, dataOffset, dataLength); 48 | return XmlConvert.DeserializeObject(xml); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/Serialization/Xml/XmlMessageEncoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Xml; 4 | using System.Xml.Serialization; 5 | 6 | namespace Redola.ActorModel.Serialization 7 | { 8 | internal class XmlMessageEncoder : IMessageEncoder 9 | { 10 | public XmlMessageEncoder() 11 | { 12 | this.CompressionEnabled = true; 13 | 14 | this.Settings = new XmlWriterSettings() 15 | { 16 | Indent = false, 17 | OmitXmlDeclaration = true, 18 | NewLineHandling = NewLineHandling.None, 19 | }; 20 | this.Namespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); 21 | } 22 | 23 | public bool CompressionEnabled { get; set; } 24 | 25 | public XmlWriterSettings Settings { get; set; } 26 | public XmlSerializerNamespaces Namespaces { get; set; } 27 | 28 | public byte[] EncodeMessage(object message) 29 | { 30 | if (message == null) 31 | throw new ArgumentNullException("message", "The message which is to be serialized cannot be null."); 32 | 33 | if (CompressionEnabled) 34 | { 35 | var xml = XmlConvert.SerializeObject(message, this.Settings, this.Namespaces); 36 | return GZipCompression.Compress(Encoding.UTF8.GetBytes(xml)); 37 | } 38 | else 39 | { 40 | var xml = XmlConvert.SerializeObject(message, this.Settings, this.Namespaces); 41 | return Encoding.UTF8.GetBytes(xml); 42 | } 43 | } 44 | 45 | public byte[] EncodeMessage(T message) 46 | { 47 | if (message == null) 48 | throw new ArgumentNullException("message", "The message which is to be serialized cannot be null."); 49 | 50 | if (CompressionEnabled) 51 | { 52 | var xml = XmlConvert.SerializeObject(message, this.Settings, this.Namespaces); 53 | return GZipCompression.Compress(Encoding.UTF8.GetBytes(xml)); 54 | } 55 | else 56 | { 57 | var xml = XmlConvert.SerializeObject(message, this.Settings, this.Namespaces); 58 | return Encoding.UTF8.GetBytes(xml); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Redola/Redola.ActorModel/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.DynamicProxy.CastleIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.DynamicProxy.CastleIntegration")] 5 | [assembly: Guid("17b964e4-8d0f-4077-8f5a-7654e6403d09")] 6 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.DynamicProxy.CastleIntegration/Redola.Rpc.DynamicProxy.CastleIntegration.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {17B964E4-8D0F-4077-8F5A-7654E6403D09} 8 | Library 9 | Properties 10 | Redola.Rpc.DynamicProxy.CastleIntegration 11 | Redola.Rpc.DynamicProxy.CastleIntegration 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Castle.Core.4.1.0\lib\net45\Castle.Core.dll 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | SolutionVersion.cs 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {05e69e70-97ff-4fff-b106-e423b6f51a00} 57 | Redola.ActorModel 58 | 59 | 60 | {465f580d-f09f-4362-a6ee-40b2627b11a4} 61 | Redola.Rpc 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.DynamicProxy.CastleIntegration/ServiceProxyGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Castle.DynamicProxy; 3 | 4 | namespace Redola.Rpc.DynamicProxy.CastleIntegration 5 | { 6 | public class ServiceProxyGenerator : IServiceProxyGenerator 7 | { 8 | private static readonly IProxyGenerator _proxyGenerator = new ProxyGenerator(); 9 | 10 | private IServiceResolver _serviceResolver; 11 | 12 | public ServiceProxyGenerator(IServiceResolver serviceResolver) 13 | { 14 | if (serviceResolver == null) 15 | throw new ArgumentNullException("serviceResolver"); 16 | _serviceResolver = serviceResolver; 17 | } 18 | 19 | public T CreateServiceProxy(RpcHandler handler, RpcMethodFixture fixture) 20 | { 21 | return CreateServiceProxy(handler, fixture, new RandomServiceLoadBalancingStrategy()); 22 | } 23 | 24 | public T CreateServiceProxy(RpcHandler handler, RpcMethodFixture fixture, IServiceLoadBalancingStrategy strategy) 25 | { 26 | var proxy = _proxyGenerator.CreateInterfaceProxyWithoutTarget( 27 | typeof(T), 28 | new ProxyGenerationOptions(), 29 | new IInterceptor[] 30 | { 31 | new ServiceProxyInterceptor( 32 | typeof(T), 33 | _serviceResolver, 34 | handler, 35 | fixture, 36 | strategy) 37 | }); 38 | return (T)proxy; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.DynamicProxy.CastleIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/Actor/ConsulActorRegistryEntry.cs: -------------------------------------------------------------------------------- 1 | using Redola.ActorModel; 2 | 3 | namespace Redola.Rpc.ServiceDiscovery.ConsulIntegration 4 | { 5 | public class ConsulActorRegistryEntry 6 | { 7 | public ActorIdentity ActorIdentity { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return string.Format("{0}", this.ActorIdentity); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/ConsulServiceDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Redola.ActorModel; 5 | 6 | namespace Redola.Rpc.ServiceDiscovery.ConsulIntegration 7 | { 8 | public class ConsulServiceDirectory : IServiceDirectory 9 | { 10 | private ConsulServiceRegistry _registry; 11 | 12 | public ConsulServiceDirectory(ConsulServiceRegistry registry) 13 | { 14 | if (registry == null) 15 | throw new ArgumentNullException("registry"); 16 | _registry = registry; 17 | } 18 | 19 | public void RegisterService(ActorIdentity actor, Type serviceType) 20 | { 21 | _registry.RegisterService(actor, serviceType.FullName); 22 | } 23 | 24 | public void RegisterService(ActorIdentity actor, Type serviceType, IEnumerable tags) 25 | { 26 | _registry.RegisterService(actor, serviceType.FullName, tags); 27 | } 28 | 29 | public void DeregisterService(ActorIdentity actor, Type serviceType) 30 | { 31 | _registry.DeregisterService(actor.Type, actor.Name, serviceType.FullName); 32 | } 33 | 34 | public void DeregisterService(string actorType, string actorName, Type serviceType) 35 | { 36 | _registry.DeregisterService(actorType, actorName, serviceType.FullName); 37 | } 38 | 39 | public IEnumerable GetActors(Type serviceType) 40 | { 41 | return _registry.GetServices(serviceType.FullName).Select(s => s.ServiceActor); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/ConsulServiceDiscovery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.Rpc.ServiceDiscovery.ConsulIntegration 6 | { 7 | public class ConsulServiceDiscovery : IServiceDiscovery 8 | { 9 | private ConsulServiceRegistry _registry; 10 | 11 | public ConsulServiceDiscovery(ConsulServiceRegistry registry) 12 | { 13 | if (registry == null) 14 | throw new ArgumentNullException("registry"); 15 | _registry = registry; 16 | } 17 | 18 | public IEnumerable Discover(Type serviceType) 19 | { 20 | return _registry.GetServices(serviceType.FullName).Select(s => new ServiceActor(s.ServiceActor.Type, s.ServiceActor.Name)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.ServiceDiscovery.ConsulIntegration")] 5 | [assembly: Guid("dedff96e-4b91-4648-b25f-43e6489f19c7")] 6 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/Service/ConsulServiceRegistryEntry.cs: -------------------------------------------------------------------------------- 1 | using Redola.ActorModel; 2 | 3 | namespace Redola.Rpc.ServiceDiscovery.ConsulIntegration 4 | { 5 | public class ConsulServiceRegistryEntry 6 | { 7 | public string ServiceType { get; set; } 8 | public ActorIdentity ServiceActor { get; set; } 9 | 10 | public override string ToString() 11 | { 12 | return string.Format("{0}", this.ServiceType); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.ConsulIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Actor/LocalXmlFileActorRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Redola.ActorModel; 6 | 7 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 8 | { 9 | public class LocalXmlFileActorRegistry 10 | { 11 | private string _localXmlFilePath = string.Empty; 12 | private XmlActorRegistry _registry; 13 | 14 | public LocalXmlFileActorRegistry(string localXmlFilePath) 15 | { 16 | if (string.IsNullOrEmpty(localXmlFilePath)) 17 | throw new ArgumentNullException("localXmlFilePath"); 18 | if (!File.Exists(localXmlFilePath)) 19 | throw new FileNotFoundException("Cannot find the xml file.", localXmlFilePath); 20 | _localXmlFilePath = localXmlFilePath; 21 | 22 | var fileContent = File.ReadAllText(_localXmlFilePath); 23 | _registry = XmlConvert.DeserializeObject(fileContent); 24 | } 25 | 26 | public string LocalXmlFilePath 27 | { 28 | get { return _localXmlFilePath; } 29 | } 30 | 31 | public IEnumerable GetEntries() 32 | { 33 | return _registry.Entries.Select(e => e.ActorIdentity); 34 | } 35 | 36 | public static LocalXmlFileActorRegistry Load(string localXmlFilePath) 37 | { 38 | var registry = new LocalXmlFileActorRegistry(localXmlFilePath); 39 | return registry; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Actor/XmlActorRegistry.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Serialization; 3 | 4 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 5 | { 6 | [XmlType(TypeName = "Registry")] 7 | public class XmlActorRegistry 8 | { 9 | [XmlArray(ElementName = "Entries")] 10 | public List Entries { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Actor/XmlActorRegistryEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | using Redola.ActorModel; 3 | 4 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 5 | { 6 | [XmlType(TypeName = "Entry")] 7 | public class XmlActorRegistryEntry 8 | { 9 | [XmlElement(ElementName = "ActorIdentity")] 10 | public ActorIdentity ActorIdentity { get; set; } 11 | 12 | public override string ToString() 13 | { 14 | return string.Format("{0}", this.ActorIdentity); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/LocalXmlFileServiceDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Redola.ActorModel; 5 | 6 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 7 | { 8 | public class LocalXmlFileServiceDirectory : IServiceDirectory 9 | { 10 | private LocalXmlFileServiceRegistry _registry; 11 | 12 | public LocalXmlFileServiceDirectory(LocalXmlFileServiceRegistry registry) 13 | { 14 | if (registry == null) 15 | throw new ArgumentNullException("registry"); 16 | _registry = registry; 17 | } 18 | 19 | public void RegisterService(ActorIdentity actor, Type serviceType) 20 | { 21 | } 22 | 23 | public void RegisterService(ActorIdentity actor, Type serviceType, IEnumerable tags) 24 | { 25 | } 26 | 27 | public void DeregisterService(ActorIdentity actor, Type serviceType) 28 | { 29 | } 30 | 31 | public void DeregisterService(string actorType, string actorName, Type serviceType) 32 | { 33 | } 34 | 35 | public IEnumerable GetActors(Type serviceType) 36 | { 37 | return _registry.GetEntries() 38 | .Where(s => s.ServiceType == serviceType.FullName) 39 | .Select(s => s.ServiceActor); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/LocalXmlFileServiceDiscovery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 6 | { 7 | public class LocalXmlFileServiceDiscovery : IServiceDiscovery 8 | { 9 | private LocalXmlFileServiceRegistry _registry; 10 | 11 | public LocalXmlFileServiceDiscovery(LocalXmlFileServiceRegistry registry) 12 | { 13 | if (registry == null) 14 | throw new ArgumentNullException("registry"); 15 | _registry = registry; 16 | } 17 | 18 | public IEnumerable Discover(Type serviceType) 19 | { 20 | return _registry.GetEntries() 21 | .Where(s => s.ServiceType == serviceType.FullName) 22 | .Select(s => new ServiceActor(s.ServiceActor.Type, s.ServiceActor.Name)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.ServiceDiscovery.XmlIntegration")] 5 | [assembly: Guid("d708e4c4-c49d-4554-a960-bc8688f8bc49")] 6 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Serialization/XmlConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Xml; 4 | using System.Xml.Serialization; 5 | 6 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 7 | { 8 | public class XmlConvert 9 | { 10 | public static string SerializeObject(object obj) 11 | { 12 | if (obj == null) return string.Empty; 13 | return SerializeObject(obj.GetType(), obj); 14 | } 15 | 16 | public static string SerializeObject(T obj) 17 | { 18 | return SerializeObject(typeof(T), obj); 19 | } 20 | 21 | public static string SerializeObject(Type typeOfObject, object obj) 22 | { 23 | string str = null; 24 | MemoryStream ms = null; 25 | 26 | try 27 | { 28 | XmlSerializer xs = new XmlSerializer(typeOfObject); 29 | 30 | ms = new MemoryStream(); 31 | using (var xtw = new XmlTextWriter(ms, System.Text.Encoding.UTF8) 32 | { 33 | Formatting = System.Xml.Formatting.Indented 34 | }) 35 | { 36 | ms = null; 37 | xs.Serialize(xtw, obj); 38 | xtw.BaseStream.Seek(0, SeekOrigin.Begin); 39 | using (StreamReader sr = new StreamReader(xtw.BaseStream)) 40 | { 41 | str = sr.ReadToEnd(); 42 | } 43 | } 44 | } 45 | finally 46 | { 47 | if (ms != null) 48 | { 49 | ms.Close(); 50 | ms = null; 51 | } 52 | } 53 | 54 | return str; 55 | } 56 | 57 | public static T DeserializeObject(string xml) 58 | { 59 | if (string.IsNullOrEmpty(xml)) return default(T); 60 | 61 | using (var reader = new StringReader(xml)) 62 | { 63 | XmlSerializer xs = new XmlSerializer(typeof(T)); 64 | return (T)xs.Deserialize(reader); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Service/LocalXmlFileServiceRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 6 | { 7 | public class LocalXmlFileServiceRegistry 8 | { 9 | private string _localXmlFilePath = string.Empty; 10 | private XmlServiceRegistry _registry; 11 | 12 | public LocalXmlFileServiceRegistry(string localXmlFilePath) 13 | { 14 | if (string.IsNullOrEmpty(localXmlFilePath)) 15 | throw new ArgumentNullException("localXmlFilePath"); 16 | if (!File.Exists(localXmlFilePath)) 17 | throw new FileNotFoundException("Cannot find the xml file.", localXmlFilePath); 18 | _localXmlFilePath = localXmlFilePath; 19 | 20 | var fileContent = File.ReadAllText(_localXmlFilePath); 21 | _registry = XmlConvert.DeserializeObject(fileContent); 22 | } 23 | 24 | public string LocalXmlFilePath 25 | { 26 | get { return _localXmlFilePath; } 27 | } 28 | 29 | public IEnumerable GetEntries() 30 | { 31 | return _registry.Entries; 32 | } 33 | 34 | public static LocalXmlFileServiceRegistry Load(string localXmlFilePath) 35 | { 36 | var registry = new LocalXmlFileServiceRegistry(localXmlFilePath); 37 | return registry; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Service/XmlServiceRegistry.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Serialization; 3 | 4 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 5 | { 6 | [XmlType(TypeName = "Registry")] 7 | public class XmlServiceRegistry 8 | { 9 | [XmlArray(ElementName = "Entries")] 10 | public List Entries { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/Service/XmlServiceRegistryEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | using Redola.ActorModel; 3 | 4 | namespace Redola.Rpc.ServiceDiscovery.XmlIntegration 5 | { 6 | [XmlType(TypeName = "Entry")] 7 | public class XmlServiceRegistryEntry 8 | { 9 | [XmlElement(ElementName = "ServiceType")] 10 | public string ServiceType { get; set; } 11 | [XmlElement(ElementName = "ServiceActor")] 12 | public ActorIdentity ServiceActor { get; set; } 13 | 14 | public override string ToString() 15 | { 16 | return string.Format("{0}", this.ServiceType); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc.ServiceDiscovery.XmlIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/ActorMessage/ActorMessageDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ActorMessageDecoder : IActorMessageDecoder 6 | { 7 | private IObjectDecoder _decoder; 8 | 9 | public ActorMessageDecoder(IObjectDecoder decoder) 10 | { 11 | _decoder = decoder; 12 | } 13 | 14 | public ActorMessageEnvelope DecodeEnvelope(byte[] data, int offset, int count) 15 | { 16 | return _decoder.Decode(data, offset, count); 17 | } 18 | 19 | public T DecodeMessage(byte[] data, int offset, int count) 20 | { 21 | return _decoder.Decode(data, offset, count); 22 | } 23 | 24 | public T DecodeEnvelopeMessage(byte[] data, int offset, int count) 25 | { 26 | var envelope = DecodeEnvelope(data, offset, count); 27 | return DecodeMessage(envelope.MessageData, 0, envelope.MessageData.Length); 28 | } 29 | 30 | public object DecodeMessage(Type type, byte[] data, int offset, int count) 31 | { 32 | return _decoder.Decode(type, data, offset, count); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/ActorMessage/ActorMessageEncoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public class ActorMessageEncoder : IActorMessageEncoder 4 | { 5 | private IObjectEncoder _encoder; 6 | 7 | public ActorMessageEncoder(IObjectEncoder encoder) 8 | { 9 | _encoder = encoder; 10 | } 11 | 12 | public byte[] EncodeMessage(object message) 13 | { 14 | return _encoder.Encode(message); 15 | } 16 | 17 | public byte[] EncodeMessage(T message) 18 | { 19 | return _encoder.Encode(message); 20 | } 21 | 22 | public byte[] EncodeMessageEnvelope(T message) 23 | { 24 | var envelope = new ActorMessageEnvelope() 25 | { 26 | MessageType = typeof(T).Name, 27 | MessageData = EncodeMessage(message), 28 | }; 29 | return _encoder.Encode(envelope); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/ActorMessage/IActorMessageDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IActorMessageDecoder 6 | { 7 | ActorMessageEnvelope DecodeEnvelope(byte[] data, int offset, int count); 8 | T DecodeMessage(byte[] data, int offset, int count); 9 | T DecodeEnvelopeMessage(byte[] data, int offset, int count); 10 | object DecodeMessage(Type type, byte[] data, int offset, int count); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/ActorMessage/IActorMessageEncoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IActorMessageEncoder 4 | { 5 | byte[] EncodeMessage(object message); 6 | byte[] EncodeMessage(T message); 7 | byte[] EncodeMessageEnvelope(T message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/Compression/GZipCompression.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | 4 | namespace Redola.Rpc 5 | { 6 | internal static class GZipCompression 7 | { 8 | public static byte[] Compress(byte[] raw) 9 | { 10 | return Compress(raw, 0, raw.Length); 11 | } 12 | 13 | public static byte[] Compress(byte[] raw, int offset, int count) 14 | { 15 | using (var memory = new MemoryStream()) 16 | { 17 | using (var gzip = new GZipStream(memory, CompressionMode.Compress, true)) 18 | { 19 | gzip.Write(raw, offset, count); 20 | } 21 | return memory.ToArray(); 22 | } 23 | } 24 | 25 | public static byte[] Decompress(byte[] gzip) 26 | { 27 | return Decompress(gzip, 0, gzip.Length); 28 | } 29 | 30 | public static byte[] Decompress(byte[] gzip, int offset, int count) 31 | { 32 | using (var input = new MemoryStream(gzip, offset, count)) 33 | using (var stream = new GZipStream(input, CompressionMode.Decompress)) 34 | { 35 | const int size = 1024; 36 | byte[] buffer = new byte[size]; 37 | using (var memory = new MemoryStream()) 38 | { 39 | int readCount = 0; 40 | do 41 | { 42 | readCount = stream.Read(buffer, 0, size); 43 | if (readCount > 0) 44 | { 45 | memory.Write(buffer, 0, readCount); 46 | } 47 | } 48 | while (readCount > 0); 49 | 50 | return memory.ToArray(); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/IObjectDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IObjectDecoder 6 | { 7 | T Decode(byte[] data); 8 | T Decode(byte[] data, int count); 9 | T Decode(byte[] data, int offset, int count); 10 | object Decode(Type type, byte[] data, int offset, int count); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/IObjectEncoder.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Redola.Rpc 3 | { 4 | public interface IObjectEncoder 5 | { 6 | byte[] Encode(object obj); 7 | byte[] Encode(T obj); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/Protobuf/ProtocolBuffersConvert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public static class ProtocolBuffersConvert 7 | { 8 | public static byte[] SerializeObject(object obj) 9 | { 10 | byte[] data; 11 | using (var stream = new MemoryStream()) 12 | { 13 | ProtoBuf.Serializer.NonGeneric.Serialize(stream, obj); 14 | data = stream.ToArray(); 15 | } 16 | 17 | return data; 18 | } 19 | 20 | public static byte[] SerializeObject(T obj) 21 | { 22 | byte[] data; 23 | using (var stream = new MemoryStream()) 24 | { 25 | ProtoBuf.Serializer.Serialize(stream, obj); 26 | data = stream.ToArray(); 27 | } 28 | 29 | return data; 30 | } 31 | 32 | public static object DeserializeObject(Type type, byte[] data) 33 | { 34 | return DeserializeObject(type, data, 0, data.Length); 35 | } 36 | 37 | public static object DeserializeObject(Type type, byte[] data, int dataOffset, int dataLength) 38 | { 39 | object obj = null; 40 | using (var stream = new MemoryStream(data, dataOffset, dataLength)) 41 | { 42 | obj = ProtoBuf.Serializer.NonGeneric.Deserialize(type, stream); 43 | } 44 | 45 | return obj; 46 | } 47 | 48 | public static T DeserializeObject(byte[] data) 49 | { 50 | return DeserializeObject(data, 0, data.Length); 51 | } 52 | 53 | public static T DeserializeObject(byte[] data, int dataOffset, int dataLength) 54 | { 55 | T obj = default(T); 56 | using (var stream = new MemoryStream(data, dataOffset, dataLength)) 57 | { 58 | obj = ProtoBuf.Serializer.Deserialize(stream); 59 | } 60 | 61 | return obj; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/Protobuf/ProtocolBuffersObjectDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ProtocolBuffersObjectDecoder : IObjectDecoder 6 | { 7 | public ProtocolBuffersObjectDecoder() 8 | { 9 | this.CompressionEnabled = true; 10 | } 11 | 12 | public bool CompressionEnabled { get; set; } 13 | 14 | public T Decode(byte[] data) 15 | { 16 | return Decode(data, data.Length); 17 | } 18 | 19 | public T Decode(byte[] data, int count) 20 | { 21 | return Decode(data, 0, count); 22 | } 23 | 24 | public T Decode(byte[] data, int offset, int count) 25 | { 26 | if (data == null) 27 | throw new ArgumentNullException("The data to be deserialized cannot be null."); 28 | 29 | if (CompressionEnabled) 30 | { 31 | return ProtocolBuffersConvert.DeserializeObject(GZipCompression.Decompress(data, offset, count)); 32 | } 33 | else 34 | { 35 | return ProtocolBuffersConvert.DeserializeObject(data, offset, count); 36 | } 37 | } 38 | 39 | public object Decode(Type type, byte[] data, int offset, int count) 40 | { 41 | if (type == null) 42 | throw new ArgumentNullException("The type to be deserialized cannot be null."); 43 | if (data == null) 44 | throw new ArgumentNullException("The data to be deserialized cannot be null."); 45 | 46 | if (CompressionEnabled) 47 | { 48 | return ProtocolBuffersConvert.DeserializeObject(type, GZipCompression.Decompress(data, offset, count)); 49 | } 50 | else 51 | { 52 | return ProtocolBuffersConvert.DeserializeObject(type, data, offset, count); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Encoding/Protobuf/ProtocolBuffersObjectEncoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ProtocolBuffersObjectEncoder : IObjectEncoder 6 | { 7 | public ProtocolBuffersObjectEncoder() 8 | { 9 | this.CompressionEnabled = true; 10 | } 11 | 12 | public bool CompressionEnabled { get; set; } 13 | 14 | public byte[] Encode(object obj) 15 | { 16 | if (obj == null) 17 | throw new ArgumentNullException("The object to be serialized cannot be null."); 18 | 19 | var raw = ProtocolBuffersConvert.SerializeObject(obj); 20 | if (CompressionEnabled) 21 | { 22 | return GZipCompression.Compress(raw); 23 | } 24 | else 25 | { 26 | return raw; 27 | } 28 | } 29 | 30 | public byte[] Encode(T obj) 31 | { 32 | if (obj == null) 33 | throw new ArgumentNullException("The object to be serialized cannot be null."); 34 | 35 | var raw = ProtocolBuffersConvert.SerializeObject(obj); 36 | if (CompressionEnabled) 37 | { 38 | return GZipCompression.Compress(raw); 39 | } 40 | else 41 | { 42 | return raw; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Messaging/Envelope/ActorMessageEnvelope.proto: -------------------------------------------------------------------------------- 1 | package Redola.ActorModel; 2 | 3 | option java_package = "com.redola.rpc"; 4 | option java_outer_classname = "ActorEnvelope"; 5 | 6 | message ActorMessageEnvelope 7 | { 8 | required string MessageID = 10; 9 | required int64 MessageTime = 20; 10 | 11 | optional string CorrelationID = 30; 12 | optional int64 CorrelationTime = 40; 13 | 14 | optional ActorEndpoint SourceEndpoint = 50; 15 | optional ActorEndpoint TargetEndpoint = 60; 16 | 17 | required string MessageType = 80; 18 | optional bytes MessageData = 90; 19 | } 20 | 21 | message ActorEndpoint 22 | { 23 | optional string Address = 1; 24 | } 25 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc")] 5 | [assembly: Guid("465f580d-f09f-4362-a6ee-40b2627b11a4")] 6 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RateLimiting/IRateLimiter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public interface IRateLimiter 7 | { 8 | int CurrentCount { get; } 9 | 10 | void Wait(); 11 | bool Wait(TimeSpan timeout); 12 | bool Wait(int millisecondsTimeout); 13 | 14 | Task WaitAsync(); 15 | Task WaitAsync(TimeSpan timeout); 16 | Task WaitAsync(int millisecondsTimeout); 17 | 18 | int Release(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Redola.Rpc.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redola.Rpc 5 | 0.3.2.0 6 | Redola.Rpc 7 | Dennis Gao 8 | Dennis Gao 9 | https://github.com/gaochundong/Redola/blob/master/LICENSE 10 | https://github.com/gaochundong/Redola 11 | false 12 | Redola is a lightweight C# based RPC framework. 13 | Copyright © 2015-2017, Dennis Gao. 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/ActorSender.cs: -------------------------------------------------------------------------------- 1 | using Redola.ActorModel; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ActorSender 6 | { 7 | public ActorSender() 8 | { 9 | } 10 | 11 | public ActorSender(ActorIdentity remoteActor, string channelIdentifier) 12 | { 13 | this.RemoteActor = remoteActor; 14 | this.ChannelIdentifier = channelIdentifier; 15 | } 16 | 17 | public ActorIdentity RemoteActor { get; set; } 18 | public string ChannelIdentifier { get; set; } 19 | 20 | public override string ToString() 21 | { 22 | return string.Format("RemoteActor[{0}], ChannelIdentifier[{1}]", RemoteActor, ChannelIdentifier); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/Blocking/BlockingActorMessageHandlerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public abstract class BlockingActorMessageHandlerBase : RouteActorMessageHandlerBase, IBlockingActorMessageHandler 6 | { 7 | private BlockingRouteActor _localActor; 8 | 9 | public BlockingActorMessageHandlerBase(BlockingRouteActor localActor) 10 | : base(localActor) 11 | { 12 | if (localActor == null) 13 | throw new ArgumentNullException("localActor"); 14 | _localActor = localActor; 15 | } 16 | 17 | public new BlockingRouteActor Actor { get { return _localActor; } } 18 | 19 | protected override void DoHandleMessage(ActorSender sender, ActorMessageEnvelope envelope) 20 | { 21 | if (GetAdmissibleMessageHandleStrategy(envelope.MessageType).IsOneWay) 22 | { 23 | base.DoHandleMessage(sender, envelope); 24 | } 25 | else 26 | { 27 | envelope.HandledBy(this.Actor, GetAdmissibleMessageType(envelope.MessageType), this.Actor.Decoder, sender, 28 | (object o) => 29 | { 30 | return o 31 | .GetType() 32 | .GetMethod("OnSyncMessage") 33 | .MakeGenericMethod(GetAdmissibleMessageType(envelope.MessageType)); 34 | }); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/Blocking/BlockingCallbackHolder.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class BlockingCallbackHolder 6 | { 7 | public BlockingCallbackHolder() 8 | { 9 | } 10 | 11 | public BlockingCallbackHolder(string messageID, ManualResetEvent waiter, object action) 12 | { 13 | this.MessageID = messageID; 14 | this.Waiter = waiter; 15 | this.Action = action; 16 | } 17 | 18 | public string MessageID { get; set; } 19 | public ManualResetEvent Waiter { get; set; } 20 | public object Action { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/Blocking/IBlockingActorMessageHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IBlockingActorMessageHandler : IRouteActorMessageHandler 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/IActorMessageHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IActorMessageHandler 4 | { 5 | bool CanHandleMessage(ActorMessageEnvelope envelope); 6 | void HandleMessage(ActorSender sender, ActorMessageEnvelope envelope); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/IRouteActorMessageHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IRouteActorMessageHandler : IActorMessageHandler 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/RouteActorMessageHandlerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Logrila.Logging; 5 | 6 | namespace Redola.Rpc 7 | { 8 | public abstract class RouteActorMessageHandlerBase : IRouteActorMessageHandler 9 | { 10 | private ILog _log = Logger.Get(); 11 | private RouteActor _localActor; 12 | private Dictionary _admissibleMessages = new Dictionary(); 13 | 14 | public RouteActorMessageHandlerBase(RouteActor localActor) 15 | { 16 | if (localActor == null) 17 | throw new ArgumentNullException("localActor"); 18 | _localActor = localActor; 19 | 20 | RegisterAdmissibleMessages(_admissibleMessages); 21 | } 22 | 23 | public RouteActor Actor { get { return _localActor; } } 24 | 25 | protected virtual void RegisterAdmissibleMessages(IDictionary admissibleMessages) 26 | { 27 | } 28 | 29 | protected virtual Type GetAdmissibleMessageType(string messageType) 30 | { 31 | return _admissibleMessages[messageType].MessageType; 32 | } 33 | 34 | protected virtual MessageHandleStrategy GetAdmissibleMessageHandleStrategy(string messageType) 35 | { 36 | return _admissibleMessages[messageType]; 37 | } 38 | 39 | public virtual bool CanHandleMessage(ActorMessageEnvelope envelope) 40 | { 41 | return _admissibleMessages.ContainsKey(envelope.MessageType); 42 | } 43 | 44 | public virtual void HandleMessage(ActorSender sender, ActorMessageEnvelope envelope) 45 | { 46 | if (GetAdmissibleMessageHandleStrategy(envelope.MessageType).IsAsyncPattern) 47 | { 48 | Task.Factory.StartNew(() => 49 | { 50 | try 51 | { 52 | DoHandleMessage(sender, envelope); 53 | } 54 | catch (Exception ex) 55 | { 56 | _log.Error(ex.Message, ex); 57 | } 58 | }, 59 | TaskCreationOptions.PreferFairness); 60 | } 61 | else 62 | { 63 | DoHandleMessage(sender, envelope); 64 | } 65 | } 66 | 67 | protected virtual void DoHandleMessage(ActorSender sender, ActorMessageEnvelope envelope) 68 | { 69 | envelope.HandledBy(this, GetAdmissibleMessageType(envelope.MessageType), this.Actor.Decoder, sender); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/RouteActor/Strategy/MessageHandleStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public sealed class MessageHandleStrategy 6 | { 7 | public MessageHandleStrategy() 8 | { 9 | this.IsAsyncPattern = true; 10 | this.IsOneWay = false; 11 | } 12 | 13 | public MessageHandleStrategy(Type messageType) 14 | : this() 15 | { 16 | this.MessageType = messageType; 17 | } 18 | 19 | public Type MessageType { get; set; } 20 | 21 | public bool IsAsyncPattern { get; set; } 22 | 23 | public bool IsOneWay { get; set; } 24 | 25 | public override string ToString() 26 | { 27 | return string.Format("MessageType[{0}], IsOneWay[{1}], IsAsyncPattern[{2}]", 28 | this.MessageType, this.IsOneWay, this.IsAsyncPattern); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceProxy/IServiceProxyGenerator.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IServiceProxyGenerator 4 | { 5 | T CreateServiceProxy(RpcHandler handler, RpcMethodFixture fixture); 6 | T CreateServiceProxy(RpcHandler handler, RpcMethodFixture fixture, IServiceLoadBalancingStrategy strategy); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/IServiceResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IServiceResolver 6 | { 7 | ServiceActor Resolve(Type serviceType); 8 | ServiceActor Resolve(Type serviceType, IServiceLoadBalancingStrategy strategy); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/LoadBalancing/IServiceLoadBalancingStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IServiceLoadBalancingStrategy 6 | { 7 | ServiceActor Select(IEnumerable services); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/LoadBalancing/RandomServiceLoadBalancingStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.Rpc 6 | { 7 | public class RandomServiceLoadBalancingStrategy : IServiceLoadBalancingStrategy 8 | { 9 | public ServiceActor Select(IEnumerable services) 10 | { 11 | return services.OrderBy(t => Guid.NewGuid()).FirstOrDefault(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/Retrieval/IServiceRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public interface IServiceRetriever 7 | { 8 | IEnumerable Retrieve(Type serviceType); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/Retrieval/ServiceRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public class ServiceRetriever : IServiceRetriever 7 | { 8 | private IServiceDiscovery _discovery; 9 | 10 | public ServiceRetriever(IServiceDiscovery discovery) 11 | { 12 | if (discovery == null) 13 | throw new ArgumentNullException("discovery"); 14 | _discovery = discovery; 15 | } 16 | 17 | public IEnumerable Retrieve(Type serviceType) 18 | { 19 | return _discovery.Discover(serviceType); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Client/ServiceResolver/ServiceResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ServiceResolver : IServiceResolver 6 | { 7 | private IServiceRetriever _retriever; 8 | private IServiceLoadBalancingStrategy _defaultStrategy = new RandomServiceLoadBalancingStrategy(); 9 | 10 | public ServiceResolver(IServiceRetriever retriever) 11 | { 12 | if (retriever == null) 13 | throw new ArgumentNullException("retriever"); 14 | _retriever = retriever; 15 | } 16 | 17 | public ServiceActor Resolve(Type serviceType) 18 | { 19 | if (serviceType == null) 20 | throw new ArgumentNullException("serviceType"); 21 | 22 | var services = _retriever.Retrieve(serviceType); 23 | return _defaultStrategy.Select(services); 24 | } 25 | 26 | public ServiceActor Resolve(Type serviceType, IServiceLoadBalancingStrategy strategy) 27 | { 28 | if (serviceType == null) 29 | throw new ArgumentNullException("serviceType"); 30 | if (strategy == null) 31 | throw new ArgumentNullException("strategy"); 32 | 33 | var services = _retriever.Retrieve(serviceType); 34 | return strategy.Select(services); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Discovery/IServiceDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Redola.ActorModel; 4 | 5 | namespace Redola.Rpc 6 | { 7 | public interface IServiceDirectory 8 | { 9 | void RegisterService(ActorIdentity actor, Type serviceType); 10 | void RegisterService(ActorIdentity actor, Type serviceType, IEnumerable tags); 11 | void DeregisterService(ActorIdentity actor, Type serviceType); 12 | void DeregisterService(string actorType, string actorName, Type serviceType); 13 | IEnumerable GetActors(Type serviceType); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Discovery/IServiceDiscovery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public interface IServiceDiscovery 7 | { 8 | IEnumerable Discover(Type serviceType); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Discovery/ServiceActor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | namespace Redola.Rpc 5 | { 6 | [Serializable] 7 | [XmlRoot] 8 | public class ServiceActor : IEquatable 9 | { 10 | public ServiceActor() 11 | { 12 | } 13 | 14 | public ServiceActor(string type, string name) 15 | { 16 | this.Type = type; 17 | this.Name = name; 18 | } 19 | 20 | [XmlAttribute] 21 | public string Name { get; set; } 22 | [XmlAttribute] 23 | public string Type { get; set; } 24 | 25 | public string GetKey() 26 | { 27 | return GetKey(this.Type, this.Name); 28 | } 29 | 30 | public static string GetKey(string type, string name) 31 | { 32 | return string.Format("{0}@{1}", name, type); 33 | } 34 | 35 | public static bool TryDecode(string key, out string type, out string name) 36 | { 37 | type = null; 38 | name = null; 39 | 40 | if (string.IsNullOrEmpty(key)) 41 | return false; 42 | 43 | var pair = key.Split('@'); 44 | if (pair.Length != 2) 45 | return false; 46 | 47 | name = pair[0]; 48 | type = pair[1]; 49 | return true; 50 | } 51 | 52 | public static void Decode(string key, out string type, out string name) 53 | { 54 | type = null; 55 | name = null; 56 | 57 | if (!TryDecode(key, out type, out name)) 58 | throw new ArgumentException(string.Format("Invalid actor key [{0}].", key)); 59 | } 60 | 61 | public override string ToString() 62 | { 63 | return string.Format("Name[{0}], Type[{1}]", Name, Type); 64 | } 65 | 66 | public override int GetHashCode() 67 | { 68 | return this.GetKey().GetHashCode(); 69 | } 70 | 71 | public bool Equals(ServiceActor other) 72 | { 73 | if (object.ReferenceEquals(other, null)) return false; 74 | if (object.ReferenceEquals(this, other)) return true; 75 | 76 | return (StringComparer.OrdinalIgnoreCase.Compare(this.GetKey(), other.GetKey()) == 0); 77 | } 78 | 79 | public override bool Equals(object obj) 80 | { 81 | if (object.ReferenceEquals(obj, null)) return false; 82 | 83 | return Equals(obj as ServiceActor); 84 | } 85 | 86 | public static bool operator ==(ServiceActor x, ServiceActor y) 87 | { 88 | if (object.ReferenceEquals(x, null)) 89 | { 90 | if (object.ReferenceEquals(y, null)) 91 | return true; 92 | else 93 | return false; 94 | } 95 | else 96 | { 97 | return x.Equals(y); 98 | } 99 | } 100 | 101 | public static bool operator !=(ServiceActor x, ServiceActor y) 102 | { 103 | return !(x == y); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/Contracts/ReceiveMessageContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ReceiveMessageContract : RpcMessageContract 6 | { 7 | public ReceiveMessageContract(Type messageType) 8 | : base(messageType) 9 | { 10 | if (messageType == null) 11 | throw new ArgumentNullException("messageType"); 12 | 13 | this.ReceiveMessageType = messageType; 14 | 15 | this.IsOneWay = true; 16 | } 17 | 18 | public Type ReceiveMessageType { get; protected set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/Contracts/RequestResponseMessageContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class RequestResponseMessageContract : RpcMessageContract 6 | { 7 | public RequestResponseMessageContract(Type request, Type response) 8 | : base(response) 9 | { 10 | if (request == null) 11 | throw new ArgumentNullException("request"); 12 | if (response == null) 13 | throw new ArgumentNullException("response"); 14 | 15 | this.RequestMessageType = request; 16 | this.ResponseMessageType = response; 17 | 18 | this.IsOneWay = false; 19 | } 20 | 21 | public Type RequestMessageType { get; protected set; } 22 | public Type ResponseMessageType { get; protected set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/Contracts/RpcMessageContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public abstract class RpcMessageContract 6 | { 7 | protected RpcMessageContract() 8 | { 9 | this.IsAsyncPattern = true; 10 | this.IsOneWay = false; 11 | } 12 | 13 | protected RpcMessageContract(Type messageType) 14 | : this() 15 | { 16 | if (messageType == null) 17 | throw new ArgumentNullException("messageType"); 18 | 19 | this.MessageType = messageType; 20 | } 21 | 22 | public Type MessageType { get; protected set; } 23 | 24 | public bool IsOneWay { get; protected set; } 25 | 26 | public bool IsAsyncPattern { get; set; } 27 | 28 | public override string ToString() 29 | { 30 | return string.Format("MessageType[{0}], IsOneWay[{1}], IsAsyncPattern[{2}]", 31 | this.MessageType, this.IsOneWay, this.IsAsyncPattern); 32 | } 33 | 34 | public MessageHandleStrategy ToStrategy() 35 | { 36 | return new MessageHandleStrategy(this.MessageType) 37 | { 38 | IsOneWay = this.IsOneWay, 39 | IsAsyncPattern = this.IsAsyncPattern, 40 | }; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/InvokeMethodMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ProtoBuf; 3 | 4 | namespace Redola.Rpc 5 | { 6 | [ProtoContract(UseProtoMembersOnly = true)] 7 | public class InvokeMethodMessage 8 | { 9 | public InvokeMethodMessage() 10 | { 11 | } 12 | 13 | public InvokeMethodMessage(string methodLocator, object[] methodArguments) 14 | { 15 | this.MethodLocator = methodLocator; 16 | this.MethodArguments = methodArguments; 17 | } 18 | 19 | [ProtoMember(10)] 20 | public string MethodLocator { get; set; } 21 | 22 | [ProtoIgnore] 23 | public object[] MethodArguments { get; set; } 24 | 25 | [ProtoMember(30)] 26 | public SerializableMethodArgument[] SerializableMethodArguments { get; set; } 27 | 28 | public void Serialize(IMethodArgumentEncoder encoder) 29 | { 30 | if (encoder == null) 31 | throw new ArgumentNullException("encoder"); 32 | 33 | if (this.MethodArguments == null || this.MethodArguments.Length == 0) 34 | return; 35 | 36 | this.SerializableMethodArguments = new SerializableMethodArgument[this.MethodArguments.Length]; 37 | for (int i = 0; i < this.MethodArguments.Length; i++) 38 | { 39 | var arg = this.MethodArguments[i]; 40 | this.SerializableMethodArguments[i] = new SerializableMethodArgument() 41 | { 42 | Type = arg.GetType().AssemblyQualifiedName, 43 | Bytes = encoder.Encode(arg), 44 | }; 45 | } 46 | } 47 | 48 | public void Deserialize(IMethodArgumentDecoder decoder) 49 | { 50 | if (decoder == null) 51 | throw new ArgumentNullException("decoder"); 52 | 53 | if (this.SerializableMethodArguments == null || this.SerializableMethodArguments.Length == 0) 54 | return; 55 | 56 | this.MethodArguments = new object[this.SerializableMethodArguments.Length]; 57 | for (int i = 0; i < this.SerializableMethodArguments.Length; i++) 58 | { 59 | var arg = this.SerializableMethodArguments[i]; 60 | var type = Type.GetType(arg.Type); 61 | this.MethodArguments[i] = decoder.Decode(type, arg.Bytes, 0, arg.Bytes.Length); 62 | } 63 | } 64 | 65 | public override string ToString() 66 | { 67 | return string.Format("Locator[{0}], Arguments[{1}]", 68 | this.MethodLocator, this.MethodArguments == null ? 0 : this.MethodArguments.Length); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/InvokeMethodRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ProtoBuf; 3 | 4 | namespace Redola.Rpc 5 | { 6 | [ProtoContract(UseProtoMembersOnly = true)] 7 | public class InvokeMethodRequest 8 | { 9 | public InvokeMethodRequest() 10 | { 11 | } 12 | 13 | public InvokeMethodRequest(string methodLocator, object[] methodArguments) 14 | { 15 | this.MethodLocator = methodLocator; 16 | this.MethodArguments = methodArguments; 17 | } 18 | 19 | [ProtoMember(10)] 20 | public string MethodLocator { get; set; } 21 | 22 | [ProtoIgnore] 23 | public object[] MethodArguments { get; set; } 24 | 25 | [ProtoMember(30)] 26 | public SerializableMethodArgument[] SerializableMethodArguments { get; set; } 27 | 28 | public void Serialize(IMethodArgumentEncoder encoder) 29 | { 30 | if (encoder == null) 31 | throw new ArgumentNullException("encoder"); 32 | 33 | if (this.MethodArguments == null || this.MethodArguments.Length == 0) 34 | return; 35 | 36 | this.SerializableMethodArguments = new SerializableMethodArgument[this.MethodArguments.Length]; 37 | for (int i = 0; i < this.MethodArguments.Length; i++) 38 | { 39 | var arg = this.MethodArguments[i]; 40 | this.SerializableMethodArguments[i] = new SerializableMethodArgument() 41 | { 42 | Type = arg.GetType().AssemblyQualifiedName, 43 | Bytes = encoder.Encode(arg), 44 | }; 45 | } 46 | } 47 | 48 | public void Deserialize(IMethodArgumentDecoder decoder) 49 | { 50 | if (decoder == null) 51 | throw new ArgumentNullException("decoder"); 52 | 53 | if (this.SerializableMethodArguments == null || this.SerializableMethodArguments.Length == 0) 54 | return; 55 | 56 | this.MethodArguments = new object[this.SerializableMethodArguments.Length]; 57 | for (int i = 0; i < this.SerializableMethodArguments.Length; i++) 58 | { 59 | var arg = this.SerializableMethodArguments[i]; 60 | var type = Type.GetType(arg.Type); 61 | this.MethodArguments[i] = decoder.Decode(type, arg.Bytes, 0, arg.Bytes.Length); 62 | } 63 | } 64 | 65 | public override string ToString() 66 | { 67 | return string.Format("Locator[{0}], Arguments[{1}]", 68 | this.MethodLocator, this.MethodArguments == null ? 0 : this.MethodArguments.Length); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Message/InvokeMethodResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ProtoBuf; 3 | 4 | namespace Redola.Rpc 5 | { 6 | [ProtoContract(UseProtoMembersOnly = true)] 7 | public class InvokeMethodResponse 8 | { 9 | public InvokeMethodResponse() 10 | { 11 | } 12 | 13 | public InvokeMethodResponse(string methodLocator, object methodReturnValue) 14 | { 15 | this.MethodLocator = methodLocator; 16 | this.MethodReturnValue = methodReturnValue; 17 | } 18 | 19 | [ProtoMember(10)] 20 | public string MethodLocator { get; set; } 21 | 22 | [ProtoIgnore] 23 | public object MethodReturnValue { get; set; } 24 | 25 | [ProtoMember(30)] 26 | public SerializableMethodArgument SerializableMethodReturnValue { get; set; } 27 | 28 | public void Serialize(IMethodArgumentEncoder encoder) 29 | { 30 | if (encoder == null) 31 | throw new ArgumentNullException("encoder"); 32 | 33 | if (this.MethodReturnValue == null) 34 | return; 35 | 36 | this.SerializableMethodReturnValue = new SerializableMethodArgument() 37 | { 38 | Type = this.MethodReturnValue.GetType().AssemblyQualifiedName, 39 | Bytes = encoder.Encode(this.MethodReturnValue), 40 | }; 41 | } 42 | 43 | public void Deserialize(IMethodArgumentDecoder decoder) 44 | { 45 | if (decoder == null) 46 | throw new ArgumentNullException("decoder"); 47 | 48 | if (this.SerializableMethodReturnValue == null) 49 | return; 50 | 51 | var type = Type.GetType(this.SerializableMethodReturnValue.Type); 52 | this.MethodReturnValue = decoder.Decode(type, this.SerializableMethodReturnValue.Bytes, 0, this.SerializableMethodReturnValue.Bytes.Length); 53 | } 54 | 55 | public override string ToString() 56 | { 57 | return string.Format("Locator[{0}]", this.MethodLocator); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Argument/Encoding/IMethodArgumentDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IMethodArgumentDecoder 6 | { 7 | T Decode(byte[] data, int offset, int count); 8 | object Decode(Type type, byte[] data, int offset, int count); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Argument/Encoding/IMethodArgumentEncoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public interface IMethodArgumentEncoder 4 | { 5 | byte[] Encode(object argument); 6 | byte[] Encode(T argument); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Argument/Encoding/MethodArgumentDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class MethodArgumentDecoder : IMethodArgumentDecoder 6 | { 7 | private IObjectDecoder _decoder; 8 | 9 | public MethodArgumentDecoder(IObjectDecoder decoder) 10 | { 11 | _decoder = decoder; 12 | } 13 | 14 | public T Decode(byte[] data, int offset, int count) 15 | { 16 | return _decoder.Decode(data, offset, count); 17 | } 18 | 19 | public object Decode(Type type, byte[] data, int offset, int count) 20 | { 21 | return _decoder.Decode(type, data, offset, count); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Argument/Encoding/MethodArgumentEncoder.cs: -------------------------------------------------------------------------------- 1 | namespace Redola.Rpc 2 | { 3 | public class MethodArgumentEncoder : IMethodArgumentEncoder 4 | { 5 | private IObjectEncoder _encoder; 6 | 7 | public MethodArgumentEncoder(IObjectEncoder encoder) 8 | { 9 | _encoder = encoder; 10 | } 11 | 12 | public byte[] Encode(object argument) 13 | { 14 | return _encoder.Encode(argument); 15 | } 16 | 17 | public byte[] Encode(T argument) 18 | { 19 | return _encoder.Encode(argument); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Argument/SerializableMethodArgument.cs: -------------------------------------------------------------------------------- 1 | using ProtoBuf; 2 | 3 | namespace Redola.Rpc 4 | { 5 | [ProtoContract(UseProtoMembersOnly = true)] 6 | public class SerializableMethodArgument 7 | { 8 | public SerializableMethodArgument() 9 | { 10 | } 11 | 12 | public SerializableMethodArgument(string type, byte[] bytes) 13 | { 14 | this.Type = type; 15 | this.Bytes = bytes; 16 | } 17 | 18 | [ProtoMember(10)] 19 | public string Type { get; set; } 20 | 21 | [ProtoMember(20)] 22 | public byte[] Bytes { get; set; } 23 | 24 | public override string ToString() 25 | { 26 | return string.Format("Type[{0}], Bytes[{1}]", 27 | this.Type, this.Bytes == null ? 0 : this.Bytes.Length); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Extractor/IMethodLocatorExtractor.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public interface IMethodLocatorExtractor 6 | { 7 | string Extract(MethodInfo method); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Extractor/MethodLocatorExtractor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace Redola.Rpc 6 | { 7 | public class MethodLocatorExtractor : IMethodLocatorExtractor 8 | { 9 | public MethodLocatorExtractor() 10 | { 11 | } 12 | 13 | public string Extract(MethodInfo method) 14 | { 15 | if (method == null) 16 | throw new ArgumentNullException("method"); 17 | 18 | var serviceType = method.DeclaringType; 19 | 20 | var methodLocator = string.Format("{0}/{1}", serviceType.FullName, method.Name); 21 | 22 | var parameters = method.GetParameters(); 23 | if (parameters != null && parameters.Length > 0) 24 | { 25 | methodLocator = string.Format("{0}/{1}_{2}", serviceType.FullName, method.Name, 26 | string.Join("_", parameters.Select(p => p.ParameterType.Name))); 27 | } 28 | 29 | return methodLocator; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Route/MethodRoute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public class MethodRoute 7 | { 8 | public MethodRoute(string locator, object instance, MethodInfo method) 9 | { 10 | if (string.IsNullOrWhiteSpace(locator)) 11 | throw new ArgumentNullException("locator"); 12 | if (instance == null) 13 | throw new ArgumentNullException("instance"); 14 | if (method == null) 15 | throw new ArgumentNullException("method"); 16 | 17 | this.Locator = locator; 18 | this.Instance = instance; 19 | this.Method = method; 20 | } 21 | 22 | public string Locator { get; private set; } 23 | public object Instance { get; private set; } 24 | public MethodInfo Method { get; private set; } 25 | 26 | public void Invoke(object[] methodArguments) 27 | { 28 | this.Method.Invoke(this.Instance, methodArguments); 29 | } 30 | 31 | public object InvokeReturn(object[] methodArguments) 32 | { 33 | return this.Method.Invoke(this.Instance, methodArguments); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Route/MethodRouteBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.Rpc 6 | { 7 | public class MethodRouteBuilder 8 | { 9 | private IMethodLocatorExtractor _extractor; 10 | 11 | public MethodRouteBuilder(IMethodLocatorExtractor extractor) 12 | { 13 | if (extractor == null) 14 | throw new ArgumentNullException("extractor"); 15 | _extractor = extractor; 16 | } 17 | 18 | public MethodRouteCache BuildCache(IEnumerable entries) 19 | { 20 | var cache = new MethodRouteCache(); 21 | 22 | foreach (var entry in entries) 23 | { 24 | var serviceType = entry.DeclaringType; 25 | var serviceInstance = entry.ServiceInstance; 26 | 27 | var methods = serviceType.GetMethods(); 28 | foreach (var method in methods) 29 | { 30 | var methodLocator = _extractor.Extract(method); 31 | var methodInstance = serviceInstance.GetType() 32 | .GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray()); 33 | 34 | var methodRoute = new MethodRoute(methodLocator, serviceInstance, methodInstance); 35 | cache.Add(methodRoute.Locator, methodRoute); 36 | } 37 | } 38 | 39 | return cache; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Route/MethodRouteCache.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class MethodRouteCache : Dictionary 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/Route/MethodRouteResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class MethodRouteResolver 6 | { 7 | private MethodRouteCache _routeCache; 8 | 9 | public MethodRouteResolver(MethodRouteCache routeCache) 10 | { 11 | if (routeCache == null) 12 | throw new ArgumentNullException("routeCache"); 13 | 14 | _routeCache = routeCache; 15 | } 16 | 17 | public MethodRoute Resolve(string methodLocator) 18 | { 19 | if (string.IsNullOrWhiteSpace(methodLocator)) 20 | throw new ArgumentNullException("methodLocator"); 21 | 22 | MethodRoute route = null; 23 | if (!_routeCache.TryGetValue(methodLocator, out route) || route == null) 24 | throw new InvalidOperationException(string.Format( 25 | "Cannot resolve method route [{0}].", methodLocator)); 26 | 27 | return route; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Method/RpcMethodFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class RpcMethodFixture 6 | { 7 | public RpcMethodFixture( 8 | IMethodLocatorExtractor extractor, 9 | IMethodArgumentEncoder argumentEncoder, 10 | IMethodArgumentDecoder argumentDecoder) 11 | { 12 | if (extractor == null) 13 | throw new ArgumentNullException("extractor"); 14 | if (argumentEncoder == null) 15 | throw new ArgumentNullException("argumentEncoder"); 16 | if (argumentDecoder == null) 17 | throw new ArgumentNullException("argumentDecoder"); 18 | 19 | this.Extractor = extractor; 20 | this.ArgumentEncoder = argumentEncoder; 21 | this.ArgumentDecoder = argumentDecoder; 22 | } 23 | 24 | public IMethodLocatorExtractor Extractor { get; private set; } 25 | public IMethodArgumentEncoder ArgumentEncoder { get; private set; } 26 | public IMethodArgumentDecoder ArgumentDecoder { get; private set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Server/Catalog/IServiceCatalogProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Redola.Rpc 5 | { 6 | public interface IServiceCatalogProvider 7 | { 8 | void RegisterService(T service); 9 | void RegisterService(Type declaringType, object service); 10 | IEnumerable GetServices(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Server/Catalog/ServiceCatalogProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Redola.Rpc 6 | { 7 | public class ServiceCatalogProvider : IServiceCatalogProvider 8 | { 9 | private List _entries = new List(); 10 | 11 | public ServiceCatalogProvider() 12 | { 13 | } 14 | 15 | public void RegisterService(T service) 16 | { 17 | RegisterService(typeof(T), service); 18 | } 19 | 20 | public void RegisterService(Type declaringType, object service) 21 | { 22 | if (declaringType == null) 23 | throw new ArgumentNullException("declaringType"); 24 | if (service == null) 25 | throw new ArgumentNullException("service"); 26 | 27 | lock (_entries) 28 | { 29 | if (_entries.Any(e => e.DeclaringType.Equals(declaringType))) 30 | throw new ArgumentException(string.Format( 31 | "Duplicate service entry for service type [{0}].", declaringType), "declaringType"); 32 | _entries.Add(new ServiceEntry(declaringType, service)); 33 | } 34 | } 35 | 36 | public IEnumerable GetServices() 37 | { 38 | return _entries; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/Rpc/Server/Catalog/ServiceEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Redola.Rpc 4 | { 5 | public class ServiceEntry 6 | { 7 | public ServiceEntry() 8 | { 9 | } 10 | 11 | public ServiceEntry(Type declaringType, object serviceInstance) 12 | { 13 | this.DeclaringType = declaringType; 14 | this.ServiceInstance = serviceInstance; 15 | } 16 | 17 | public Type DeclaringType { get; set; } 18 | public object ServiceInstance { get; set; } 19 | 20 | public override string ToString() 21 | { 22 | return string.Format("Type[{0}]", DeclaringType); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Redola/Redola.Rpc/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Redola/SolutionVersion.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyDescription("Redola is a lightweight C# based RPC framework.")] 5 | [assembly: AssemblyCompany("Dennis Gao")] 6 | [assembly: AssemblyProduct("Redola")] 7 | [assembly: AssemblyCopyright("Copyright © 2015-2017, Dennis Gao")] 8 | [assembly: AssemblyTrademark("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCulture("")] 11 | [assembly: AssemblyVersion("0.3.2.0")] 12 | [assembly: AssemblyFileVersion("0.3.2.0")] 13 | [assembly: ComVisible(false)] 14 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorCenter/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorCenter/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Logrila.Logging; 3 | using Logrila.Logging.NLogIntegration; 4 | using Redola.ActorModel; 5 | 6 | namespace Redola.Rpc.TestActorCenter 7 | { 8 | class Program 9 | { 10 | static ILog _log; 11 | 12 | static Program() 13 | { 14 | NLogLogger.Use(); 15 | _log = Logger.Get(); 16 | } 17 | 18 | static void Main(string[] args) 19 | { 20 | var localActorConfiguration = AppConfigActorConfiguration.Load(); 21 | var localActor = new CenterActor(localActorConfiguration); 22 | 23 | var directoryConfiguration = AppConfigCenterActorDirectoryConfiguration.Load(); 24 | var directory = new CenterActorDirectory(directoryConfiguration); 25 | localActor.Bootup(directory); 26 | 27 | while (true) 28 | { 29 | try 30 | { 31 | string text = Console.ReadLine().ToLowerInvariant(); 32 | if (text == "quit" || text == "exit") 33 | break; 34 | } 35 | catch (Exception ex) 36 | { 37 | _log.Error(ex.Message, ex); 38 | } 39 | } 40 | 41 | localActor.Shutdown(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorCenter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestActorCenter")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestActorCenter")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("dcb0784a-622e-4ef6-ba1b-79099da8d648")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorCenter/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/CalcClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorClient 6 | { 7 | internal class CalcClient : RpcHandler, ICalcService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public CalcClient(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | protected override IEnumerable RegisterRpcMessageContracts() 17 | { 18 | var messages = new List(); 19 | 20 | messages.Add(new RequestResponseMessageContract(typeof(AddRequest), typeof(AddResponse))); 21 | 22 | return messages; 23 | } 24 | 25 | public AddResponse Add(AddRequest request) 26 | { 27 | return this.Send("server", request); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/HelloClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorClient 6 | { 7 | internal class HelloClient : RpcHandler, IHelloService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public HelloClient(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | protected override IEnumerable RegisterRpcMessageContracts() 17 | { 18 | var messages = new List(); 19 | 20 | messages.Add(new RequestResponseMessageContract(typeof(HelloRequest), typeof(HelloResponse))); 21 | messages.Add(new RequestResponseMessageContract(typeof(Hello10000Request), typeof(Hello10000Response))); 22 | 23 | return messages; 24 | } 25 | 26 | public HelloResponse Hello(HelloRequest request) 27 | { 28 | return this.Send("server", request); 29 | } 30 | 31 | public Hello10000Response Hello10000(Hello10000Request request) 32 | { 33 | return this.Send("server", request); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/OrderClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorClient 6 | { 7 | internal class OrderClient : RpcHandler, IOrderService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public OrderClient(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | protected override IEnumerable RegisterRpcMessageContracts() 17 | { 18 | var messages = new List(); 19 | 20 | messages.Add(new RequestResponseMessageContract(typeof(PlaceOrderRequest), typeof(PlaceOrderResponse))); 21 | 22 | return messages; 23 | } 24 | 25 | public PlaceOrderResponse PlaceOrder(PlaceOrderRequest request) 26 | { 27 | return this.Send("server", request); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/OrderEventService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorClient 6 | { 7 | internal class OrderEventService : RpcHandler, IOrderEventService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public OrderEventService(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | protected override IEnumerable RegisterRpcMessageContracts() 17 | { 18 | var messages = new List(); 19 | 20 | messages.Add(new ReceiveMessageContract(typeof(OrderDeliveredNotification))); 21 | 22 | return messages; 23 | } 24 | 25 | private void OnOrderDeliveredNotification(ActorSender sender, ActorMessageEnvelope request) 26 | { 27 | _log.DebugFormat("OnOrderDeliveredNotification, MessageID[{0}], CorrelationID[{1}].", 28 | request.MessageID, request.CorrelationID); 29 | 30 | var response = new ActorMessageEnvelope() 31 | { 32 | CorrelationID = request.MessageID, 33 | CorrelationTime = request.MessageTime, 34 | Message = OrderDelivered(request.Message), 35 | }; 36 | 37 | this.BeginReply(sender.ChannelIdentifier, response); 38 | } 39 | 40 | public OrderDeliveredConfirmation OrderDelivered(OrderDeliveredNotification request) 41 | { 42 | _log.DebugFormat("OrderDelivered, OrderID[{0}], OrderStatus[{1}].", 43 | request.OrderID, request.OrderStatus); 44 | return new OrderDeliveredConfirmation() { OrderID = request.OrderID }; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestActorClient")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestActorClient")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("94b31d55-c3a9-43c9-8819-61753b4b2435")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorClient/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/CalcService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorServer 6 | { 7 | internal class CalcService : RpcHandler, ICalcService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public CalcService(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | public CalcService(RpcActor localActor, IRateLimiter rateLimiter) 17 | : base(localActor, rateLimiter) 18 | { 19 | } 20 | 21 | protected override IEnumerable RegisterRpcMessageContracts() 22 | { 23 | var messages = new List(); 24 | 25 | messages.Add(new ReceiveMessageContract(typeof(AddRequest))); 26 | 27 | return messages; 28 | } 29 | 30 | private void OnAddRequest(ActorSender sender, ActorMessageEnvelope request) 31 | { 32 | var response = new ActorMessageEnvelope() 33 | { 34 | CorrelationID = request.MessageID, 35 | CorrelationTime = request.MessageTime, 36 | Message = Add(request.Message), 37 | }; 38 | 39 | this.BeginReply(sender.ChannelIdentifier, response); 40 | } 41 | 42 | public AddResponse Add(AddRequest request) 43 | { 44 | var response = new AddResponse() { Result = request.X + request.Y }; 45 | _log.DebugFormat("Add, X={0}, Y={1}, Result={2}", request.X, request.Y, response.Result); 46 | return response; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/HelloService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Logrila.Logging; 4 | using Redola.Rpc.TestContracts; 5 | 6 | namespace Redola.Rpc.TestActorServer 7 | { 8 | internal class HelloService : RpcHandler, IHelloService 9 | { 10 | private ILog _log = Logger.Get(); 11 | 12 | public HelloService(RpcActor localActor) 13 | : base(localActor) 14 | { 15 | } 16 | 17 | public HelloService(RpcActor localActor, IRateLimiter rateLimiter) 18 | : base(localActor, rateLimiter) 19 | { 20 | } 21 | 22 | protected override IEnumerable RegisterRpcMessageContracts() 23 | { 24 | var messages = new List(); 25 | 26 | messages.Add(new ReceiveMessageContract(typeof(HelloRequest))); 27 | messages.Add(new ReceiveMessageContract(typeof(Hello10000Request))); 28 | 29 | return messages; 30 | } 31 | 32 | private void OnHelloRequest(ActorSender sender, ActorMessageEnvelope request) 33 | { 34 | var response = new ActorMessageEnvelope() 35 | { 36 | CorrelationID = request.MessageID, 37 | CorrelationTime = request.MessageTime, 38 | Message = Hello(request.Message), 39 | }; 40 | 41 | this.BeginReply(sender.ChannelIdentifier, response); 42 | } 43 | 44 | private void OnHello10000Request(ActorSender sender, ActorMessageEnvelope request) 45 | { 46 | var response = new ActorMessageEnvelope() 47 | { 48 | CorrelationID = request.MessageID, 49 | CorrelationTime = request.MessageTime, 50 | Message = Hello10000(request.Message), 51 | }; 52 | 53 | this.BeginReply(sender.ChannelIdentifier, response); 54 | } 55 | 56 | public HelloResponse Hello(HelloRequest request) 57 | { 58 | _log.DebugFormat("Hello, Text={0}", request.Text); 59 | return new HelloResponse() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 60 | } 61 | 62 | public Hello10000Response Hello10000(Hello10000Request request) 63 | { 64 | return new Hello10000Response() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/OrderEventClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorServer 6 | { 7 | internal class OrderEventClient : RpcHandler, IOrderEventService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public OrderEventClient(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | protected override IEnumerable RegisterRpcMessageContracts() 17 | { 18 | var messages = new List(); 19 | 20 | messages.Add(new RequestResponseMessageContract(typeof(OrderDeliveredNotification), typeof(OrderDeliveredConfirmation))); 21 | 22 | return messages; 23 | } 24 | 25 | public OrderDeliveredConfirmation OrderDelivered(OrderDeliveredNotification request) 26 | { 27 | return this.Send("client", request); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/OrderService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestActorServer 6 | { 7 | internal class OrderService : RpcHandler, IOrderService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public OrderService(RpcActor localActor) 12 | : base(localActor) 13 | { 14 | } 15 | 16 | public OrderService(RpcActor localActor, IRateLimiter rateLimiter) 17 | : base(localActor, rateLimiter) 18 | { 19 | } 20 | 21 | protected override IEnumerable RegisterRpcMessageContracts() 22 | { 23 | var messages = new List(); 24 | 25 | messages.Add(new ReceiveMessageContract(typeof(PlaceOrderRequest))); 26 | 27 | return messages; 28 | } 29 | 30 | private void OnPlaceOrderRequest(ActorSender sender, ActorMessageEnvelope request) 31 | { 32 | var response = new ActorMessageEnvelope() 33 | { 34 | CorrelationID = request.MessageID, 35 | CorrelationTime = request.MessageTime, 36 | Message = PlaceOrder(request.Message), 37 | }; 38 | 39 | this.BeginReply(sender.ChannelIdentifier, response); 40 | } 41 | 42 | public PlaceOrderResponse PlaceOrder(PlaceOrderRequest request) 43 | { 44 | _log.DebugFormat("PlaceOrder, OrderID={0}", request.Contract.OrderID); 45 | return new PlaceOrderResponse() 46 | { 47 | Contract = request.Contract, 48 | Order = request.Contract, 49 | ErrorCode = PlaceOrderErrorCode.OrderPlaced, 50 | }; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestActorServer")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestActorServer")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("c06d311c-bd6a-4e5c-86df-1bda937a5fe0")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestActorServer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Calc.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | // Generated from: Tests/Redola.Rpc.TestContracts/Calc.proto 11 | namespace Redola.Rpc.TestContracts 12 | { 13 | [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"AddRequest")] 14 | public partial class AddRequest : global::ProtoBuf.IExtensible 15 | { 16 | public AddRequest() {} 17 | 18 | private int _X; 19 | [global::ProtoBuf.ProtoMember(10, IsRequired = true, Name=@"X", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)] 20 | public int X 21 | { 22 | get { return _X; } 23 | set { _X = value; } 24 | } 25 | private int _Y; 26 | [global::ProtoBuf.ProtoMember(20, IsRequired = true, Name=@"Y", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)] 27 | public int Y 28 | { 29 | get { return _Y; } 30 | set { _Y = value; } 31 | } 32 | private global::ProtoBuf.IExtension extensionObject; 33 | global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) 34 | { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } 35 | } 36 | 37 | [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"AddResponse")] 38 | public partial class AddResponse : global::ProtoBuf.IExtensible 39 | { 40 | public AddResponse() {} 41 | 42 | private int _Result; 43 | [global::ProtoBuf.ProtoMember(10, IsRequired = true, Name=@"Result", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)] 44 | public int Result 45 | { 46 | get { return _Result; } 47 | set { _Result = value; } 48 | } 49 | private global::ProtoBuf.IExtension extensionObject; 50 | global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) 51 | { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } 52 | } 53 | 54 | public interface ICalcService 55 | { 56 | Redola.Rpc.TestContracts.AddResponse Add(Redola.Rpc.TestContracts.AddRequest request); 57 | 58 | } 59 | 60 | 61 | } -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Calc.proto: -------------------------------------------------------------------------------- 1 | package Redola.Rpc.TestContracts; 2 | 3 | option java_package = "com.redola.rpc.testcontracts"; 4 | option java_outer_classname = "Calc"; 5 | 6 | message AddRequest 7 | { 8 | required int32 X = 10; 9 | required int32 Y = 20; 10 | } 11 | 12 | message AddResponse 13 | { 14 | required int32 Result = 10; 15 | } 16 | 17 | service CalcService 18 | { 19 | rpc Add (AddRequest) returns (AddResponse); 20 | } 21 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Hello.proto: -------------------------------------------------------------------------------- 1 | package Redola.Rpc.TestContracts; 2 | 3 | option java_package = "com.redola.rpc.testcontracts"; 4 | option java_outer_classname = "Hello"; 5 | 6 | message HelloRequest 7 | { 8 | required string Text = 10; 9 | } 10 | 11 | message HelloResponse 12 | { 13 | required string Text = 10; 14 | } 15 | 16 | message Hello10000Request 17 | { 18 | required string Text = 10; 19 | } 20 | 21 | message Hello10000Response 22 | { 23 | required string Text = 10; 24 | } 25 | 26 | service HelloService 27 | { 28 | rpc Hello (HelloRequest) returns (HelloResponse); 29 | rpc Hello10000 (Hello10000Request) returns (Hello10000Response); 30 | } 31 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Order.proto: -------------------------------------------------------------------------------- 1 | package Redola.Rpc.TestContracts; 2 | 3 | option java_package = "com.redola.rpc.testcontracts"; 4 | option java_outer_classname = "Orders"; 5 | 6 | message Order 7 | { 8 | required string OrderID = 10; 9 | required string ItemID = 20; 10 | required double BuyCount = 70; 11 | } 12 | 13 | enum PlaceOrderErrorCode 14 | { 15 | OrderPlaced = 0; 16 | UnknownPlaceOrderError = 1; 17 | } 18 | 19 | message PlaceOrderRequest 20 | { 21 | required Order Contract = 15; 22 | } 23 | 24 | message PlaceOrderResponse 25 | { 26 | required Order Contract = 15; 27 | 28 | optional Order Order = 60; 29 | required PlaceOrderErrorCode ErrorCode = 70; 30 | } 31 | 32 | service OrderService 33 | { 34 | rpc PlaceOrder (PlaceOrderRequest) returns (PlaceOrderResponse); 35 | } 36 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/OrderEvent.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | // Generated from: Tests/Redola.Rpc.TestContracts/OrderEvent.proto 11 | namespace Redola.Rpc.TestContracts 12 | { 13 | [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"OrderDeliveredNotification")] 14 | public partial class OrderDeliveredNotification : global::ProtoBuf.IExtensible 15 | { 16 | public OrderDeliveredNotification() {} 17 | 18 | private string _OrderID; 19 | [global::ProtoBuf.ProtoMember(10, IsRequired = true, Name=@"OrderID", DataFormat = global::ProtoBuf.DataFormat.Default)] 20 | public string OrderID 21 | { 22 | get { return _OrderID; } 23 | set { _OrderID = value; } 24 | } 25 | private int _OrderStatus; 26 | [global::ProtoBuf.ProtoMember(15, IsRequired = true, Name=@"OrderStatus", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)] 27 | public int OrderStatus 28 | { 29 | get { return _OrderStatus; } 30 | set { _OrderStatus = value; } 31 | } 32 | private global::ProtoBuf.IExtension extensionObject; 33 | global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) 34 | { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } 35 | } 36 | 37 | [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"OrderDeliveredConfirmation")] 38 | public partial class OrderDeliveredConfirmation : global::ProtoBuf.IExtensible 39 | { 40 | public OrderDeliveredConfirmation() {} 41 | 42 | private string _OrderID; 43 | [global::ProtoBuf.ProtoMember(10, IsRequired = true, Name=@"OrderID", DataFormat = global::ProtoBuf.DataFormat.Default)] 44 | public string OrderID 45 | { 46 | get { return _OrderID; } 47 | set { _OrderID = value; } 48 | } 49 | private global::ProtoBuf.IExtension extensionObject; 50 | global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) 51 | { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } 52 | } 53 | 54 | public interface IOrderEventService 55 | { 56 | Redola.Rpc.TestContracts.OrderDeliveredConfirmation OrderDelivered(Redola.Rpc.TestContracts.OrderDeliveredNotification request); 57 | 58 | } 59 | 60 | 61 | } -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/OrderEvent.proto: -------------------------------------------------------------------------------- 1 | package Redola.Rpc.TestContracts; 2 | 3 | option java_package = "com.redola.rpc.testcontracts"; 4 | option java_outer_classname = "OrderEvents"; 5 | 6 | message OrderDeliveredNotification 7 | { 8 | required string OrderID = 10; 9 | required int32 OrderStatus = 15; 10 | } 11 | 12 | message OrderDeliveredConfirmation 13 | { 14 | required string OrderID = 10; 15 | } 16 | 17 | service OrderEventService 18 | { 19 | rpc OrderDelivered (OrderDeliveredNotification) returns (OrderDeliveredConfirmation); 20 | } 21 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestContracts")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany(" Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestContracts")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("faccbf0d-1634-42f6-8011-22d3dda54f18")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/Redola.Rpc.TestContracts.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FACCBF0D-1634-42F6-8011-22D3DDA54F18} 8 | Library 9 | Properties 10 | Redola.Rpc.TestContracts 11 | Redola.Rpc.TestContracts 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\Redola\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestContracts/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/Modules/TestContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Happer; 4 | using Happer.Http; 5 | 6 | namespace Redola.Rpc.TestHttpRelay.XmlIntegration 7 | { 8 | public class TestContainer : IModuleContainer 9 | { 10 | private Dictionary _modules = new Dictionary(); 11 | 12 | public TestContainer() 13 | { 14 | } 15 | 16 | public void AddModule(Module module) 17 | { 18 | _modules.Add(module.GetType().FullName, module); 19 | } 20 | 21 | public IEnumerable GetAllModules() 22 | { 23 | return _modules.Values; 24 | } 25 | 26 | public Module GetModule(Type moduleType) 27 | { 28 | return _modules[moduleType.FullName]; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/Modules/TestModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Happer.Http; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestHttpRelay.XmlIntegration 6 | { 7 | internal class TestModule : Module 8 | { 9 | private IHelloService _helloService; 10 | private ICalcService _calcService; 11 | 12 | public TestModule(IHelloService helloService, ICalcService calcService) 13 | { 14 | _helloService = helloService; 15 | _calcService = calcService; 16 | 17 | Get("/empty", x => 18 | { 19 | return string.Empty; 20 | }); 21 | Get("/time", x => 22 | { 23 | return DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"); 24 | }); 25 | Get("/hello", x => 26 | { 27 | var response = _helloService.Hello(new HelloRequest() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }); 28 | return response == null ? string.Empty : response.Text; 29 | }); 30 | Get("/hello10000", x => 31 | { 32 | var response = _helloService.Hello10000(new Hello10000Request() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }); 33 | return response == null ? string.Empty : response.Text; 34 | }); 35 | Get("/add", x => 36 | { 37 | var response = _calcService.Add(new AddRequest() { X = 1, Y = 2 }); 38 | return string.Format("Result = {0}, Time = {1}", response.Result.ToString(), DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff")); 39 | }); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Happer; 3 | using Happer.Hosting.Self; 4 | using Logrila.Logging; 5 | using Logrila.Logging.NLogIntegration; 6 | using Redola.ActorModel; 7 | using Redola.Rpc.DynamicProxy.CastleIntegration; 8 | using Redola.Rpc.ServiceDiscovery.XmlIntegration; 9 | using Redola.Rpc.TestContracts; 10 | 11 | namespace Redola.Rpc.TestHttpRelay.XmlIntegration 12 | { 13 | class Program 14 | { 15 | static ILog _log; 16 | 17 | static Program() 18 | { 19 | NLogLogger.Use(); 20 | _log = Logger.Get(); 21 | } 22 | 23 | static void Main(string[] args) 24 | { 25 | var localXmlFileLocalActorPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\LocalActor.xml"; 26 | var localXmlFileLocalActorConfiguration = LocalXmlFileActorConfiguration.Load(localXmlFileLocalActorPath); 27 | var localActor = new RpcActor(localXmlFileLocalActorConfiguration); 28 | 29 | var localXmlFileActorRegistryPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\ActorRegistry.xml"; 30 | var localXmlFileActorRegistry = LocalXmlFileActorRegistry.Load(localXmlFileActorRegistryPath); 31 | var actorDirectory = new LocalXmlFileActorDirectory(localXmlFileActorRegistry); 32 | 33 | var localXmlFileServiceRegistryPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\ServiceRegistry.xml"; 34 | var serviceRegistry = LocalXmlFileServiceRegistry.Load(localXmlFileServiceRegistryPath); 35 | var serviceDiscovery = new LocalXmlFileServiceDiscovery(serviceRegistry); 36 | var serviceRetriever = new ServiceRetriever(serviceDiscovery); 37 | var serviceResolver = new ServiceResolver(serviceRetriever); 38 | var proxyGenerator = new ServiceProxyGenerator(serviceResolver); 39 | 40 | var rpcClient = new RpcClient(localActor, actorDirectory, proxyGenerator); 41 | 42 | var helloClient = rpcClient.Resolve(); 43 | var calcClient = rpcClient.Resolve(); 44 | 45 | rpcClient.Bootup(); 46 | 47 | var container = new TestContainer(); 48 | container.AddModule(new TestModule(helloClient, calcClient)); 49 | 50 | var bootstrapper = new Bootstrapper(); 51 | var engine = bootstrapper.BootWith(container); 52 | 53 | string uri = "http://localhost:3202/"; 54 | var host = new SelfHost(engine, new Uri(uri)); 55 | host.Start(); 56 | Console.WriteLine("Server is listening on [{0}].", uri); 57 | 58 | Console.WriteLine("Type something to stop ..."); 59 | Console.ReadKey(); 60 | 61 | host.Stop(); 62 | rpcClient.Shutdown(); 63 | Console.WriteLine("Stopped. Goodbye!"); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestHttpRelay.XmlIntegration")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestHttpRelay.XmlIntegration")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("01eaa9d3-a299-4ec2-bade-843ba7500174")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/XmlConfiguration/ActorRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/XmlConfiguration/LocalActor.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/XmlConfiguration/ServiceRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Redola.Rpc.TestContracts.IHelloService 6 | 7 | 8 | 9 | Redola.Rpc.TestContracts.ICalcService 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestHttpRelay.XmlIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.ConsulIntegration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.ConsulIntegration/OrderEventService.cs: -------------------------------------------------------------------------------- 1 | using Logrila.Logging; 2 | using Redola.Rpc.TestContracts; 3 | 4 | namespace Redola.Rpc.TestRpcClient.ConsulIntegration 5 | { 6 | internal class OrderEventService : IOrderEventService 7 | { 8 | private ILog _log = Logger.Get(); 9 | 10 | public OrderDeliveredConfirmation OrderDelivered(OrderDeliveredNotification request) 11 | { 12 | _log.DebugFormat("OrderDelivered, OrderID[{0}].", request.OrderID); 13 | return new OrderDeliveredConfirmation() 14 | { 15 | OrderID = request.OrderID, 16 | }; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.ConsulIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestRpcClient.ConsulIntegration")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestRpcClient.ConsulIntegration")] 9 | [assembly: AssemblyCopyright("Copyright © 2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("28b35945-becd-4638-85e6-f340e1910a3c")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.ConsulIntegration/XmlConfiguration/LocalActor.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.ConsulIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestRpcClient.XmlIntegration")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestRpcClient.XmlIntegration")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("80a02268-72b7-4312-af7a-c1ddd9654364")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/XmlConfiguration/ActorRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/XmlConfiguration/LocalActor.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/XmlConfiguration/ServiceRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Redola.Rpc.TestContracts.IHelloService 6 | 7 | 8 | 9 | Redola.Rpc.TestContracts.ICalcService 10 | 11 | 12 | 13 | Redola.Rpc.TestContracts.IOrderService 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcClient.XmlIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/CalcService.cs: -------------------------------------------------------------------------------- 1 | using Logrila.Logging; 2 | using Redola.Rpc.TestContracts; 3 | 4 | namespace Redola.Rpc.TestRpcServer.ConsulIntegration 5 | { 6 | internal class CalcService : ICalcService 7 | { 8 | private ILog _log = Logger.Get(); 9 | 10 | public AddResponse Add(AddRequest request) 11 | { 12 | var response = new AddResponse() { Result = request.X + request.Y }; 13 | _log.DebugFormat("Add, X={0}, Y={1}, Result={2}", request.X, request.Y, response.Result); 14 | return response; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/HelloService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestRpcServer.ConsulIntegration 6 | { 7 | internal class HelloService : IHelloService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public HelloResponse Hello(HelloRequest request) 12 | { 13 | _log.DebugFormat("Hello, Text={0}", request.Text); 14 | return new HelloResponse() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 15 | } 16 | 17 | public Hello10000Response Hello10000(Hello10000Request request) 18 | { 19 | return new Hello10000Response() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/OrderService.cs: -------------------------------------------------------------------------------- 1 | using Logrila.Logging; 2 | using Redola.Rpc.TestContracts; 3 | 4 | namespace Redola.Rpc.TestRpcServer.ConsulIntegration 5 | { 6 | internal class OrderService : IOrderService 7 | { 8 | private ILog _log = Logger.Get(); 9 | 10 | public PlaceOrderResponse PlaceOrder(PlaceOrderRequest request) 11 | { 12 | _log.DebugFormat("PlaceOrder, OrderID={0}", request.Contract.OrderID); 13 | return new PlaceOrderResponse() 14 | { 15 | Contract = request.Contract, 16 | Order = request.Contract, 17 | ErrorCode = PlaceOrderErrorCode.OrderPlaced, 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestRpcServer.ConsulIntegration")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestRpcServer.ConsulIntegration")] 9 | [assembly: AssemblyCopyright("Copyright © 2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("b15b8512-f25e-4e0c-a598-2e440754dd41")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/XmlConfiguration/LocalActor.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.ConsulIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/CalcService.cs: -------------------------------------------------------------------------------- 1 | using Logrila.Logging; 2 | using Redola.Rpc.TestContracts; 3 | 4 | namespace Redola.Rpc.TestRpcServer.XmlIntegration 5 | { 6 | internal class CalcService : ICalcService 7 | { 8 | private ILog _log = Logger.Get(); 9 | 10 | public AddResponse Add(AddRequest request) 11 | { 12 | var response = new AddResponse() { Result = request.X + request.Y }; 13 | _log.DebugFormat("Add, X={0}, Y={1}, Result={2}", request.X, request.Y, response.Result); 14 | return response; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/HelloService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Logrila.Logging; 3 | using Redola.Rpc.TestContracts; 4 | 5 | namespace Redola.Rpc.TestRpcServer.XmlIntegration 6 | { 7 | internal class HelloService : IHelloService 8 | { 9 | private ILog _log = Logger.Get(); 10 | 11 | public HelloResponse Hello(HelloRequest request) 12 | { 13 | _log.DebugFormat("Hello, Text={0}", request.Text); 14 | return new HelloResponse() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 15 | } 16 | 17 | public Hello10000Response Hello10000(Hello10000Request request) 18 | { 19 | return new Hello10000Response() { Text = DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff") }; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/OrderService.cs: -------------------------------------------------------------------------------- 1 | using Logrila.Logging; 2 | using Redola.Rpc.TestContracts; 3 | 4 | namespace Redola.Rpc.TestRpcServer.XmlIntegration 5 | { 6 | internal class OrderService : IOrderService 7 | { 8 | private ILog _log = Logger.Get(); 9 | 10 | public PlaceOrderResponse PlaceOrder(PlaceOrderRequest request) 11 | { 12 | _log.DebugFormat("PlaceOrder, OrderID[{0}].", request.Contract.OrderID); 13 | return new PlaceOrderResponse() 14 | { 15 | Contract = request.Contract, 16 | Order = request.Contract, 17 | ErrorCode = PlaceOrderErrorCode.OrderPlaced, 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Logrila.Logging; 3 | using Logrila.Logging.NLogIntegration; 4 | using Redola.ActorModel; 5 | using Redola.Rpc.ServiceDiscovery.XmlIntegration; 6 | using Redola.Rpc.TestContracts; 7 | 8 | namespace Redola.Rpc.TestRpcServer.XmlIntegration 9 | { 10 | class Program 11 | { 12 | static ILog _log; 13 | 14 | static Program() 15 | { 16 | NLogLogger.Use(); 17 | _log = Logger.Get(); 18 | } 19 | 20 | static void Main(string[] args) 21 | { 22 | var localXmlFileLocalActorPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\LocalActor.xml"; 23 | var localXmlFileLocalActorConfiguration = LocalXmlFileActorConfiguration.Load(localXmlFileLocalActorPath); 24 | var localActor = new RpcActor(localXmlFileLocalActorConfiguration); 25 | 26 | var localXmlFileActorRegistryPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\ActorRegistry.xml"; 27 | var localXmlFileActorRegistry = LocalXmlFileActorRegistry.Load(localXmlFileActorRegistryPath); 28 | var actorDirectory = new LocalXmlFileActorDirectory(localXmlFileActorRegistry); 29 | 30 | var localXmlFileServiceRegistryPath = Environment.CurrentDirectory + @"\\XmlConfiguration\\ServiceRegistry.xml"; 31 | var serviceRegistry = LocalXmlFileServiceRegistry.Load(localXmlFileServiceRegistryPath); 32 | var serviceDirectory = new LocalXmlFileServiceDirectory(serviceRegistry); 33 | 34 | var serviceCatalog = new ServiceCatalogProvider(); 35 | serviceCatalog.RegisterService(new HelloService()); 36 | serviceCatalog.RegisterService(new CalcService()); 37 | serviceCatalog.RegisterService(new OrderService()); 38 | 39 | var rpcServer = new RpcServer(localActor, actorDirectory, serviceCatalog, serviceDirectory); 40 | 41 | rpcServer.Bootup(); 42 | 43 | while (true) 44 | { 45 | try 46 | { 47 | string text = Console.ReadLine().ToLowerInvariant(); 48 | if (text == "quit" || text == "exit") 49 | { 50 | break; 51 | } 52 | else if (text == "reconnect") 53 | { 54 | rpcServer.Shutdown(); 55 | rpcServer.Bootup(); 56 | } 57 | else 58 | { 59 | _log.WarnFormat("Cannot parse the operation for input [{0}].", text); 60 | } 61 | } 62 | catch (Exception ex) 63 | { 64 | _log.Error(ex.Message, ex); 65 | } 66 | } 67 | 68 | rpcServer.Shutdown(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("Redola.Rpc.TestRpcServer.XmlIntegration")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("Dennis Gao")] 8 | [assembly: AssemblyProduct("Redola.Rpc.TestRpcServer.XmlIntegration")] 9 | [assembly: AssemblyCopyright("Copyright © 2016-2017, Dennis Gao")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | [assembly: Guid("a4ce7bce-7f4d-4e4b-afc1-4a70f9a886a8")] 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/XmlConfiguration/ActorRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/XmlConfiguration/LocalActor.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/XmlConfiguration/ServiceRegistry.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tests/Redola.Rpc.TestRpcServer.XmlIntegration/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/Licence.txt: -------------------------------------------------------------------------------- 1 | The core Protocol Buffers technology is provided courtesy of Google. 2 | At the time of writing, this is released under the BSD license. 3 | Full details can be found here: 4 | 5 | http://code.google.com/p/protobuf/ 6 | 7 | 8 | This .NET implementation is Copyright 2008 Marc Gravell 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | http://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/protobuf-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaochundong/Redola/329de3273a53535fe96d9e920aae269c9c483cf6/tools/codegen/protobuf/dotnet/protobuf-net.dll -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/protoc-license.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | http://code.google.com/p/protobuf/ 4 | 5 | This package contains a precompiled Win32 binary version of the protocol buffer 6 | compiler (protoc). This binary is intended for Windows users who want to 7 | use Protocol Buffers in Java or Python but do not want to compile protoc 8 | themselves. To install, simply place this binary somewhere in your PATH. 9 | 10 | This binary was built using MinGW, but the output is the same regardless of 11 | the C++ compiler used. 12 | 13 | You will still need to download the source code package in order to obtain the 14 | Java or Python runtime libraries. Get it from: 15 | http://code.google.com/p/protobuf/downloads/ 16 | -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/protogen.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaochundong/Redola/329de3273a53535fe96d9e920aae269c9c483cf6/tools/codegen/protobuf/dotnet/protogen.exe -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/protogen.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tools/codegen/protobuf/dotnet/xml.xslt: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Xml template for protobuf-net. 13 | 14 | This template writes the proto descriptor as xml. 15 | No options available. 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tools/codegen/protobuf/google/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaochundong/Redola/329de3273a53535fe96d9e920aae269c9c483cf6/tools/codegen/protobuf/google/protoc.exe -------------------------------------------------------------------------------- /tools/codegen/protobuf/google/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | http://code.google.com/p/protobuf/ 4 | 5 | This package contains a precompiled Win32 binary version of the protocol buffer 6 | compiler (protoc). This binary is intended for Windows users who want to 7 | use Protocol Buffers in Java or Python but do not want to compile protoc 8 | themselves. To install, simply place this binary somewhere in your PATH. 9 | 10 | This binary was built using MinGW, but the output is the same regardless of 11 | the C++ compiler used. 12 | 13 | You will still need to download the source code package in order to obtain the 14 | Java or Python runtime libraries. Get it from: 15 | http://code.google.com/p/protobuf/downloads/ 16 | -------------------------------------------------------------------------------- /tools/protobuf-codegen-csharp.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET CODEGENTOOL="tools\codegen\protobuf\dotnet\protogen.exe" 4 | 5 | FOR %%i IN (Tests\Redola.Rpc.TestContracts\*.proto) DO (CALL :codegen %%i) 6 | 7 | GOTO :done 8 | 9 | :codegen 10 | SET protofile=%1 11 | SET csfile=%protofile:proto=cs% 12 | SET csfile=%csfile:cscol=Protocol% 13 | ECHO %CODEGENTOOL% -i:%protofile% -o:%csfile% -q 14 | %CODEGENTOOL% -i:%protofile% -o:%csfile% -q 15 | GOTO :EOF 16 | 17 | :done 18 | ECHO DONE! 19 | -------------------------------------------------------------------------------- /tools/protobuf-codegen-java.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET CODEGENTOOL="tools\codegen\protobuf\google\protoc.exe" 4 | 5 | FOR %%i IN (Tests\Redola.Rpc.TestContracts\*.proto) DO (CALL :codegen %%i) 6 | 7 | GOTO :done 8 | 9 | :codegen 10 | SET protofile=%1 11 | ECHO %CODEGENTOOL% --java_out=. %protofile% 12 | %CODEGENTOOL% --java_out=. %protofile% 13 | GOTO :EOF 14 | 15 | :done 16 | ECHO DONE! 17 | -------------------------------------------------------------------------------- /tools/protobuf-codegen-python.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET CODEGENTOOL="tools\codegen\protobuf\google\protoc.exe" 4 | 5 | FOR %%i IN (Tests\Redola.Rpc.TestContracts\*.proto) DO (CALL :codegen %%i) 6 | 7 | GOTO :done 8 | 9 | :codegen 10 | SET protofile=%1 11 | ECHO %CODEGENTOOL% --python_out=. %protofile% 12 | %CODEGENTOOL% --python_out=. %protofile% 13 | GOTO :EOF 14 | 15 | :done 16 | ECHO DONE! 17 | --------------------------------------------------------------------------------