Elixir游戏服设计三
玩家进程用gen_server来建模,我不直接使用 use GenServer, 而是使用exactor,该库可以去掉反锁的接口定义。
我们新建一个 player_server_manager app吧, 使用 mix new player_server_manager --sup, 会给我们增加sup。然后在mix.exs里增加exactor的依赖如下:
defp deps do
[{:exactor, "~> 2.2"}]
end
跑 mix deps.get,成功了依赖就准备好了。
默认生成的player_server_manager.ex
defmodule PlayerServerManager do
use Application # See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec, warn: false children = [
# Define workers and child supervisors to be supervised
# worker(PlayerServerManager.Worker, [arg1, arg2, arg3]),
] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: PlayerServerManager.Supervisor]
Supervisor.start_link(children, opts)
end
end
玩家进程就叫player_server吧。把它改成我需要的。
defmodule PlayerServerManager do
use Application # See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec, warn: false children = [
# Define workers and child supervisors to be supervised
worker(PlayerServer, [], restart: :temporary),
] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :simple_one_for_one, name: PlayerServerManager.Supervisor]
Supervisor.start_link(children, opts)
end
end
因为玩家进程是动态创建的,因此采用simple_one_for_one, 同时我不需要默认传参数,还有我不需要重启。
好了现在让我们编写PlayerServer模块(现在是简单的,而且我还未知有什么需要调整的,后续随着服务器设计而演化吧)。
让我们先增加个查询钻石的接口吧。
defmodule PlayerServer do use ExActor.GenServer defstart start_link(player), do: initial_state(%{player: player, socket: nil})
defcall gem, state: state, do: reply(state.player.base_info.gem)
end
我们在PlayerServerManager里增加启动接口如下
def start_player_server(%Player{} = player) do
Supervisor.start_child(PlayerServerManager.Supervisor, [player])
end
在player_server_manager_test.exs里增加测试代码
defmodule PlayerServerManagerTest do
use ExUnit.Case
doctest PlayerServerManager setup do
Application.stop(:player_server_manager)
:ok = Application.start(:player_server_manager)
end setup do
player = Player.new(0)
{:ok, player: player}
end
test "start player_server", %{player: player} do
assert {:ok, pid} = PlayerServerManager.start_player_server(player)
assert PlayerServer.gem(pid) == 0
end
end
测试通过。
写到这里发现之前Player和BaseInfo @behavior 实际上应该为@hehaviour, 既然之前没报错,我就把它去掉了,测试依然通过。说明其实可能只需要
defdelegate。
好了,这一章就到这。遗留的问题有,我们通常需要给玩家进程一个名字,而不是通过pid,如果是单节点的话, local 注册已经足够,如果是跨服访问,我们需要一个分布式的注册机制(实际上分布式注册机制容易有坑,如无必要,千万别)。比如gporc,比如syn。 前者比较有名,我以前在erlang用过,之前有碰到莫名奇妙的问题。所以下章试试syn吧。
Elixir游戏服设计三的更多相关文章
- Elixir游戏服设计五
在<Elixir游戏服设计一>里提到,按照系统功能划分成app要保证原子性很难, 现在想想也没那么难.保证原子性,无非就是需要某个单点去完成操作.那么选择玩家进程去做原子性工作就可以了. ...
- Elixir游戏服设计一
在Erlang游戏服设计总结http://www.cnblogs.com/rubyist/p/5530575.html里, 我提到我想要的游戏服设计方法,希望以应用做为基础构建块.最近我在学习elix ...
- 简单Elixir游戏服设计- 游戏玩法介绍
抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...
- 简单Elixir游戏服设计-玩家进程跑起来
有了玩家模型,我们试试让玩家进程跑起来. 需要搞个PlayerSupervisor来负责启动和监控玩家进程. defmodule PlayerSupervisor do use Supervisor ...
- 关于Elixir游戏服设计系列
写着写着就废球了,感觉空对空,实在没什么意思. 另外很快就要搞新项目,决定新项目就直接上elixir了.目前该做的准备工作已经探索了一些了. 以下的东西是写给同事参考的,感兴趣的可以看看,提建议更好. ...
- 简单Elixir游戏服设计-玩法simple_poker
上回介绍了玩法,现在编写了玩法的简单建模. 做到现在感觉目前还没有使用umbrella的必要(也许以后会发现必要吧),model 应用完全可以合并到game_server. 代码还在https://g ...
- 简单Elixir游戏服设计-玩家进程注册
上回说用Registry 做本地注册(跨服可以用syn,只是稍微麻烦点,需要模拟global注册机制,写个封装模块). 修改game_server 项目的mix.exs, 增加应用启动 def app ...
- Elixir游戏服设计四
上章说到我们要引入syn https://github.com/ostinelli/syn/ 看过文档,它并没有直接提供{via, Module, Name} 相关的方法.我们需要封装一下. Name ...
- Elixir游戏服设计二
搞一个例子,而没有实际的目标,做起来真是烦人.几次三番都想放弃. 后来想想,即使最后完成不了完整的服务器,把需要的知识点搞搞,摸熟悉也是好的. 这里没有完整的项目目录,主要是对需要的指点进行整理.要完 ...
随机推荐
- 深入理解line-height
什么是行间距? 古时候我们使用印刷机来出来文字.印刷出来的每个字,都位于独立的一个块中. 行间距,即传说中控制两行文字垂直距离的东东.在CSS中,line-height被用来控制行与行之间垂直距离. ...
- Mysql 分区详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt120 一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.m ...
- Ubuntu下安装NVIDIA显卡驱动的教训
今天在ubuntu16.04版本下安装了NVIDIA的显卡驱动,真的是一波十六折: 首先是在英伟达的官网上查找你自己电脑的显卡型号然后下载相应的驱动. 网址:http://www.nvidia.cn/ ...
- 如何在centos7上安装源码包
在我们使用linux的过程中,有很多程序是通过红帽官网给的系统中安装的,但是一般来说,系统更新的速度比较慢,如果这个时候我们又想用最新版的该怎么办呢?总不能一直等系统升级吧╮(╯﹏╰)╭所以,我们可以 ...
- IPsec_VPN实现技术【转载】
GRE Tunnel GRE Tunnel(General Routing Encapsulation 通用路由封装)是一种非常简单的VPN(Virtual Private Network 虚拟专用网 ...
- LINUX - awk命令之NF和$NF区别 (转)
NF和$NF 区别问答:(转)1.awk中$NF是什么意思?#pwd/usr/local/etc~# echo $PWD | awk -F/ '{print $NF}'etcNF代表:浏览记录的域的个 ...
- shell(sed/gawk)脚本(计算目录文件/验证电话号码/解析电子邮件地址)
1.计算目录文件 #!/bin/bash mypath=`echo $PATH | sed 's/:/ /g'`#注意` ` 和 ‘ ’ count= for directory in $mypath ...
- JVM(四)内存回收(二)
在上一节中"JVM(三)内存回收(一)"我讲到了垃圾回收的几种算法,算是解决了之前提到的3个问题中的最后一个. 关于内存回收,还应该了解常用的内存回收器(GC Collector) ...
- overflow使用說明
必須設置的CSS屬性: { display:block; //或者inline-block,text-overflow:ellipsis只對block或者inline-block有效 white-sp ...
- JVM菜鸟进阶高手之路七(tomcat调优以及tomcat7、8性能对比)
转载请注明原创出处,谢谢! 因为每个链路都会对其性能造成影响,应该是全链路的修改压测(ak大神经常说全链路!).本次基本就是局域网,所以并没有怎么优化,其实也应该考虑进去的. Linux系统参数层面的 ...