我是一个真正的Erlang新手(1周前开始),我正在尝试通过创建一个小而有效的聊天服务器来学习这种语言。 (当我说效率时,我的意思是我有5台服务器用来对数十万个连接客户端进行压力测试 - 百万会很棒!)
我找到了一些教程这样做,唯一的是,我找到的每个教程都是IRC。如果一个用户发送邮件,则除发件人之外的所有用户都将收到邮件。 我想稍微改变一下,并使用一对一的讨论。
搜索连接用户的最有效客户端池是什么? 我考虑过注册这个过程,因为它似乎做了我需要的一切,但我真的不认为这是更好的方法。 (或者最好的方式去做)。
有人会有这样做的建议吗?
编辑:
每个连接的客户端都会受到ID的影响。
当用户连接时,它首先发送一个登录命令来提供它的id。 当用户想要将消息发送给另一个消息时,该消息看起来像这样
[ID-NUMBER][Message] %% ID-NUMBER IS A FIXED LENGTH
当我要求“最有效的客户端池”时,我实际上正在寻找在连接的客户端列表上检索/添加/删除一个客户端的最快方法,这可能很大(数十万 - 可能是数百万) )
编辑2:
回答一些问题:
我应该使用列表编写自己的搜索客户端功能吗?
还是应该使用ets?
甚至使用register / 2 unregister / 1和whereis / 1维护我的客户端列表,使用它的唯一id作为atom,它似乎是最简单的方法,我真的不知道它是否有效,但我很确定这是丑陋的解决方案;-)?
答案 0 :(得分:2)
我也是Erlang的新手(几个月),所以我希望这可以让你走上正确的道路:)
首先,既然你是“新手”,你应该知道这些网站:
好吧,考虑一个非持久性数据库,我会建议sets
或gb_sets
模块(文档here)。
如果你想要持久化,你应该尝试dets
(参见上面的文档),但我不能说明效率,所以你应该进一步研究这个主题。
在“了解你一些Erlang”一书中,有一章关于data structures,其中sets
更适合读取密集型系统,而gb_sets
更适合平衡使用。< / p>
答案 1 :(得分:1)
我正在使用gproc作为pubsub执行类似于聊天程序的操作(类似于该页面上的演示)。每个客户端都注册为id。要查找特定客户端,请对该客户端ID进行查找。要订阅客户端,请向要订阅的客户端ID的进程添加属性。要发布,请调用gproc:send(ClientId,Message)。这包括您的用例,更基本的基于房间的聊天,并且可以处理分布式无主进程注册过程。
我没有测试过它是否可以扩展到数百万,但它使用ets进行存储,而gproc是Ulf Wiger的坚固代码。我不会指望能够编写更好的实现。
答案 2 :(得分:1)
现在,消息系统是人们在来到Erlang时想要做的事情,因为两者自然融合。但是,在继续之前,有许多事情需要研究。消息传递主要涉及以下事项:User Registration
,User Authentication
,Sessions Management
,Logging
,Message Switching/routing
e.t.c.
现在,要完成所有或大部分这些操作,需要有一个数据库,当然是IN-MEMORY,这会导致我Mnesia
或ETS Tables
。既然你是Erlang的新手,我想你还没有真正掌握这些。有一刻,您需要维护Who is communicating with who
,Who is available for Chat
e.t.c.因此,您可能需要查找事物并在某些地方写东西。
另一件事是您没有告诉我们客户。它是一个Web客户端(HTTP),它是一个你在原始套接字上实现的全新协议吗?无论如何,您需要掌握一些名为Concurrency in Erlang
的东西。如果用户连接并分配了ID
,如果您的设计是A process Per User
,那么您将必须保存这些进程的Pids或根据某些条件注册它们,如果它们死于e.t.c,则再次监视它们。这让我想到OTP
和Supervision trees
。但是,有很多关于客户端和服务器交互,您需要的网络通信e.t.c的更多信息。或者它只是一个简单的Erlang RPC项目,您正在为自己的修订做什么?
编辑
使用ETS Tables
或使用Mnesia RAM tables
。不要考虑注册这些Pid或将它们存储在列表,数组或集合中。查看this solution