因为经常买双色球,嫌每次对彩票号麻烦,于是休息的时候做了个双色球兑奖的小程序,做完了发现业务还挺复杂的,于是改DDD重做设计,拆分服务,各种折腾...,不过这和本随笔没多大关系,等差不多了再总结一下,有空就写出来。

上面说了拆服务,拆成了录入,开奖,兑奖三个服务,三个服务开始是用消息队列的,不过后来发现其实就是服务的领域对象之间的交互,就联想到了Actor,面向对象于是一切都是对象,actor也是一切都是actor,看着就门当户对,于是就干掉消息队列。。。细节以后有机会再说。

上面其实也和这随笔没啥关系,有关系的是,因为时间关系,没去了解akka的文档,于是好奇一件事,服务器连接地址中的"user"是哪来的:

//var section = (AkkaConfigurationSection)ConfigurationManager.GetSection("akka");

//using (var system = ActorSystem.Create("TestClient", section.AkkaConfig))

            using (var system = ActorSystem.Create("TestClient"))
{
var actor = system.ActorSelection("akka.tcp://TestServer@localhost:8081/user/tester"); while (true)
{
var input = Console.ReadLine();
if (input.Equals(""))
{
actor.Tell(new DTO(""));
}
else if (input.Equals(""))
{
actor.Tell(new DTO(""));
}
else
{
actor.Tell(new DTO("H W"));
}
}
}

上面是客户端,下面是服务端:

             var config = ConfigurationFactory.ParseString(@"
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
applied-adapters = []
transport-protocol = tcp
port = 8081
hostname = localhost
}
}
}
"); using (var system = ActorSystem.Create("TestServer", config))
{
system.ActorOf<TestDTOActor>("tester"); Console.ReadLine();
}

文档想必很多,最近有别的要看,于是想想看看代码得了,反正一时还不会用到生产环境,到时候再说吧,先解决好奇的问题。

于是首先是ActorSystem的实现类ActorSystemImpl,system.ActorOf<TestDTOActor>("tester")对服务端路径影响的应该是ActorOf:

        public override IActorRef SystemActorOf<TActor>(string name = null)
{
return _provider.SystemGuardian.Cell.ActorOf<TActor>(name);
}

于是找找_provider:

        public ActorSystemImpl(string name, Config config)
{
if(!Regex.Match(name, "^[a-zA-Z0-9][a-zA-Z0-9-]*$").Success)
throw new ArgumentException(
"invalid ActorSystem name [" + name +
"], must contain only word characters (i.e. [a-zA-Z0-9] plus non-leading '-')");
if(config == null)
throw new ArgumentNullException("config"); _name = name;
ConfigureSettings(config);
ConfigureEventStream();
ConfigureProvider();
ConfigureTerminationCallbacks();
ConfigureScheduler();
ConfigureSerialization();
ConfigureMailboxes();
ConfigureDispatchers();
ConfigureActorProducerPipeline();
} private void ConfigureSettings(Config config)
{
_settings = new Settings(this, config);
} private void ConfigureProvider()
{
Type providerType = Type.GetType(_settings.ProviderClass);
global::System.Diagnostics.Debug.Assert(providerType != null, "providerType != null");
var provider = (IActorRefProvider)Activator.CreateInstance(providerType, _name, _settings, _eventStream);
_provider = provider;
}
        public Settings(ActorSystem system, Config config)
{
_userConfig = config;
_fallbackConfig = ConfigurationFactory.Default();
RebuildConfig(); System = system; ConfigVersion = Config.GetString("akka.version");
ProviderClass = Config.GetString("akka.actor.provider");
var providerType = Type.GetType(ProviderClass);
if (providerType == null)
throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid type name : '{0}'", ProviderClass));
if (!typeof(IActorRefProvider).IsAssignableFrom(providerType))
throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid actor ref provider: '{0}'", ProviderClass)); SupervisorStrategyClass = Config.GetString("akka.actor.guardian-supervisor-strategy"); AskTimeout = Config.GetTimeSpan("akka.actor.ask-timeout", allowInfinite: true);
CreationTimeout = Config.GetTimeSpan("akka.actor.creation-timeout");
UnstartedPushTimeout = Config.GetTimeSpan("akka.actor.unstarted-push-timeout"); SerializeAllMessages = Config.GetBoolean("akka.actor.serialize-messages");
SerializeAllCreators = Config.GetBoolean("akka.actor.serialize-creators"); LogLevel = Config.GetString("akka.loglevel");
StdoutLogLevel = Config.GetString("akka.stdout-loglevel");
Loggers = Config.GetStringList("akka.loggers"); LoggerStartTimeout = Config.GetTimeSpan("akka.logger-startup-timeout"); //handled
LogConfigOnStart = Config.GetBoolean("akka.log-config-on-start");
LogDeadLetters = ;
switch (Config.GetString("akka.log-dead-letters"))
{
case "on":
case "true":
LogDeadLetters = int.MaxValue;
break;
case "off":
case "false":
LogDeadLetters = ;
break;
default:
LogDeadLetters = Config.GetInt("akka.log-dead-letters");
break;
}
LogDeadLettersDuringShutdown = Config.GetBoolean("akka.log-dead-letters-during-shutdown");
AddLoggingReceive = Config.GetBoolean("akka.actor.debug.receive");
DebugAutoReceive = Config.GetBoolean("akka.actor.debug.autoreceive");
DebugLifecycle = Config.GetBoolean("akka.actor.debug.lifecycle");
FsmDebugEvent = Config.GetBoolean("akka.actor.debug.fsm");
DebugEventStream = Config.GetBoolean("akka.actor.debug.event-stream");
DebugUnhandledMessage = Config.GetBoolean("akka.actor.debug.unhandled");
DebugRouterMisconfiguration = Config.GetBoolean("akka.actor.debug.router-misconfiguration");
Home = Config.GetString("akka.home") ?? "";
DefaultVirtualNodesFactor = Config.GetInt("akka.actor.deployment.default.virtual-nodes-factor"); SchedulerClass = Config.GetString("akka.scheduler.implementation");
//TODO: dunno.. we dont have FiniteStateMachines, dont know what the rest is
/*
final val SchedulerClass: String = getString("akka.scheduler.implementation")
final val Daemonicity: Boolean = getBoolean("akka.daemonic")
final val DefaultVirtualNodesFactor: Int = getInt("akka.actor.deployment.default.virtual-nodes-factor")
*/
}

很明显,看配置文件的akka.actor.provider:

<configuration>
<configSections>
<section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<akka>
<hocon>
<![CDATA[
akka {
actor {
provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"
}
remote {
helios.tcp {
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
applied-adapters = []
transport-protocol = tcp
port = 0
hostname = localhost
}
}
}
]]>
</hocon>
</akka>
</configuration>

于是RemoteActorRefProvider:

        public LocalActorRef SystemGuardian { get { return _local.SystemGuardian; } }

        public RemoteActorRefProvider(string systemName, Settings settings, EventStream eventStream)
{
settings.InjectTopLevelFallback(RemoteConfigFactory.Default()); var remoteDeployer = new RemoteDeployer(settings);
Func<ActorPath, IInternalActorRef> deadLettersFactory = path => new RemoteDeadLetterActorRef(this, path, eventStream);
_local = new LocalActorRefProvider(systemName, settings, eventStream, remoteDeployer, deadLettersFactory);
RemoteSettings = new RemoteSettings(settings.Config);
Deployer = remoteDeployer;
_log = _local.Log;
}

好吧,看LocalActorRefProvider:

        public void Init(ActorSystemImpl system)
{
_system = system;
//The following are the lazy val statements in Akka
var defaultDispatcher = system.Dispatchers.DefaultGlobalDispatcher;
_defaultMailbox = () => new ConcurrentQueueMailbox(); //TODO:system.Mailboxes.FromConfig(Mailboxes.DefaultMailboxId)
_rootGuardian = CreateRootGuardian(system);
_tempContainer = new VirtualPathContainer(system.Provider, _tempNode, _rootGuardian, _log);
_rootGuardian.SetTempContainer(_tempContainer);
_userGuardian = CreateUserGuardian(_rootGuardian, "user");
_systemGuardian = CreateSystemGuardian(_rootGuardian, "system", _userGuardian);
//End of lazy val _rootGuardian.Start();
// chain death watchers so that killing guardian stops the application
_systemGuardian.Tell(new Watch(_userGuardian, _systemGuardian)); //Should be SendSystemMessage
_rootGuardian.Tell(new Watch(_systemGuardian, _rootGuardian)); //Should be SendSystemMessage
_eventStream.StartDefaultLoggers(_system);
}
        private LocalActorRef CreateUserGuardian(LocalActorRef rootGuardian, string name)   //Corresponds to Akka's: override lazy val guardian: LocalActorRef
{
return CreateRootGuardianChild(rootGuardian, name, () =>
{
var props = Props.Create<GuardianActor>(UserGuardianSupervisorStrategy); var userGuardian = new LocalActorRef(_system, props, DefaultDispatcher, _defaultMailbox, rootGuardian, RootPath/name);
return userGuardian;
});
}

看样子,这个RootPath还重载了操作符:

        public static ActorPath operator /(ActorPath path, string name)
{
return new ChildActorPath(path, name, );
} public static ActorPath operator /(ActorPath path, IEnumerable<string> name)
{
var a = path;
foreach (string element in name)
{
a = a / element;
}
return a;
}

现在_userGuardian路径是看到了,生拼上去的,那么哪里用的呢

LocalActorRefProvider:

     public LocalActorRef Guardian { get { return _userGuardian; } }

RemoteActorRefProvider:

     public LocalActorRef Guardian { get { return _local.Guardian; } }

再回来看system.ActorOf<TestDTOActor>("tester")这句:

        public override IActorRef ActorOf(Props props, string name = null)
{
return _provider.Guardian.Cell.ActorOf(props, name: name);
}

这就是我自己配的provider造成的,其实还是配置问题,当然,这么看我们其实可以实现自己的provider,想怎么搞就怎么搞,有时间其实还是应该看下文档,不过想来文档应该会说怎么用什么样,当应该不会说怎么实现的,要知道为什么,怎么改,估计还是要自己看代码,此致。

Akka.net路径里的user的更多相关文章

  1. 22.访问jar包下资源路径里的文件

    访问jar包下资源路径里的文件 因为打包路径和你构建的代码路径是有差异的,想要查看真实的路径情况,可以查看编译后的classes目录下的文件结构. 想要获取资源文件流: private InputSt ...

  2. gcc 库路径里同时有相同文件名的动态库和静态库

    找不到库的处理方案 有两种方法: 一.可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行). 二.把当前路径加 ...

  3. Java Web项目里 classpath 具体指哪个路径

    classpath路径指什么 只知道把配置文件如:mybatis.xml.spring-web.xml.applicationContext.xml等放到src目录(就是存放代码.java文件的目录) ...

  4. java项目里classpath具体指哪儿个路径

    一.classpath路径指什么 只知道把配置文件如:mybatis.xml.spring-web.xml.applicationContext.xml等放到src目录(就是存放代码.java文件的目 ...

  5. AKKA文档2.1(java版)——什么是AKKA?

    可扩展的实时事务处理 我们相信编写并发.容错.可扩展的应用相当的困难.盖因大多数时候我们一直在使用错误的工具和错误的抽象等级.AKKA就是为了改变这一切的.我们利用角色模型提升了抽象等级,并且提供了一 ...

  6. Akka Typed系列:协议&行为

    引言 2019年11月6号LightBend公司发布了AKKA 2.6版本,带来了类型安全的actor,新的Akka Cluster底层通信设施——Artery,带来了更好的稳定性,使用Jackson ...

  7. Akka Typed 官方文档之随手记

    ️ 引言 近两年,一直在折腾用FP与OO共存的编程语言Scala,采取以函数式编程为主的方式,结合TDD和BDD的手段,采用Domain Driven Design的方法学,去构造DDDD应用(Dom ...

  8. https/相对路径,绝对路径

    1. htttps HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全 ...

  9. jsp--- jsp图片上传到了正确路径,但在正确路径显示不出来

    首先要说的是,路径里没有中文 图片也在正确路径 ************************************ 刷新(Refresh)一下项目

随机推荐

  1. DB1:数据库的创建和文件的修改

    在SQL Server中,使用Create Database创建数据库,使用Alter Database命令,能够修改数据库的数据文件和日志文件. 一,创建数据库 1,在创建数据库时,最佳实践是: 创 ...

  2. HTML5 语义元素(二)文本内容

    上一篇介绍的是关于页面结构方面的语义元素,本篇介绍文本内容方面,包含:<bdi>.<details>.<summary>.<mark>.<outp ...

  3. [C#] 简单的 Helper 封装 -- CookieHelper

    using System; using System.Web; namespace ConsoleApplication5 { /// <summary> /// Cookie 助手 // ...

  4. 微框架spark--api开发利器

    spark简介 Spark(注意不要同Apache Spark混淆)的设计初衷是,可以简单容易地创建REST API或Web应用程序.它是一个灵活.简洁的框架,大小只有1MB.Spark允许用户自己选 ...

  5. 2016/12/31_Python

    今天学习主要内容: Python: 1.with语句(补充昨天的文件操作) 用with打开的文件在脚本结束会自动关闭,以防普通打开方式忘记关闭文件连接 语法: with open("demo ...

  6. win7下利用ftp实现华为路由器的上传和下载

    win7下利用ftp实现华为路由器的上传和下载 1.  Win7下ftp的安装和配置 (1)开始->控制面板->程序->程序和功能->打开或关闭Windows功能 (2)在Wi ...

  7. Lucene4.4.0 开发之排序

    排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最 ...

  8. NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式

    注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...

  9. sqlyog导出json数据格式支持mysql数据转存mongodb

    <!-------------知识的力量是无限的(当然肯定还有更简单的方法)-----------!> 当我考虑将省市区三级联动数据从mysql转入mongodb时遇到了网上无直接插入mo ...

  10. nginx代理https站点(亲测)

    nginx代理https站点(亲测) 首先,我相信大家已经搞定了nginx正常代理http站点的方法,下面重点介绍代理https站点的配置方法,以及注意事项,因为目前大部分站点有转换https的需要所 ...