热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(整理)用Elixir做一个多人扑克游戏4

为什么80%的码农都做不了架构师?sockets和channels是Phoenix中用来实现实时效果的两大工具。Socketssocket是用来连接客户端与服务

为什么80%的码农都做不了架构师?>>>   hot3.png

sockets 和 channels 是Phoenix中用来实现实时效果的两大工具。

Sockets

socket是用来连接客户端与服务器的,它使用endpoint来声明:

defmodule GenPoker.Endpoint douse Phoenix.Endpoint, otp_app: :gen_pokersocket "/socket", GenPoker.PlayerSocket
end

Channels

客户端只有加入了channel之后才能发送消息。

defmodule GenPoker.PlayerSocket douse Phoenix.Socketchannel "tables:*", GenPoker.TableChannel
end

创建socket

defmodule GenPoker.PlayerSocket douse Phoenix.Sockettransport :websocket, Phoenix.Transports.WebSocketdef connect(%{"playerId" => player_id}, socket) do{:ok, assign(socket, :player_id, player_id)}enddef id(socket) do "players_socket:#{socket.assigns.player_id}"end
end

注册进程

defmodule Poker.Table douse GenServerdef start_link(table_name, sup, storage, num_seats) doGenServer.start_link(__MODULE__, [table_name, sup, storage, num_seats], name: via_tuple(table_name))enddefp via_tuple(table) do {:via, :gproc, {:n, :l, {:table, table}}}enddef whereis(table) do:gproc.whereis_name({:n, :l, {:table, table}})end
end

我们使用了gproc库来注册进程,这样就可以使用一个term而不仅仅是atom作为名字。让我们来定义Channel:

module GenPoker.TableChannel douse GenPoker.Web, :channelalias Poker.Tabledef join("tables:" <> table, _payload, socket) do{:ok, assign(socket, :table, table)}enddef handle_in(command, payload, socket) when command in ~w(sit leave buy_in cash_out deal) dotable &#61; Table.whereis(socket.assigns.table)arguments &#61; [table, socket.assigns.player_id] &#43;&#43; payloadresult &#61; apply(Table, String.to_atom(command), arguments)if result &#61;&#61; :ok dobroadcast! socket, "update", Table.get_state(table)end{:reply, result, socket}end
end

对于客户端的join请求&#xff0c;我们有不同的回复。在Javascript中可以这样写&#xff1a;

channel.push("message", arguments).receive("ok", (msg) &#61;> console.log("Got OK!")).receive("error", (msg) &#61;> console.log("Oops!"))

发送初始的state

def join("tables:" <> table, _payload, socket) dostate &#61; table |> Table.whereis |> Table.get_statepush socket, "update", state{:ok, assign(socket, :table, table)}
end

使用handle_info

def join("tables:" <> table, _payload, socket) dosend self, :after_join{:ok, assign(socket, :table, table)}
enddef handle_info(:after_join, socket) dostate &#61; socket.assigns.table |> Table.whereis |> Table.get_statepush socket, "update", state{:noreply, socket}
enddef handle_info(_, socket) do{:noreply, socket}
end

拦截消息

def handle_out("update", state, socket) dopush socket, "update", hide_other_hands(state, socket){:noreply, socket}
enddefp hide_other_hands(state, socket) doplayer_id &#61; socket.assigns.player_idhide_hand_if_current_player &#61; fn%{id: ^player_id} &#61; player -> playerplayer -> Map.delete(player, :hand)endupdate_in(state.players, fn players ->Enum.map(players, hide_hand_if_current_player)end)
end

完整代码


转:https://my.oschina.net/ljzn/blog/754811



推荐阅读
  • MongoDB高可用架构:深入解析Replica Set机制
    MongoDB的高可用架构主要依赖于其Replica Set机制。Replica Set通过多个mongod节点的协同工作,实现了数据的冗余存储和故障自动切换,确保了系统的高可用性和数据的一致性。本文将深入解析Replica Set的工作原理及其在实际应用中的配置和优化方法,帮助读者更好地理解和实施MongoDB的高可用架构。 ... [详细]
  • 本文介绍了一个基本的同步Socket程序,演示了如何实现客户端与服务器之间的简单消息传递。此外,文章还概述了Socket的基本工作流程,并计划在未来探讨同步与异步Socket的区别。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • GNU 发布的 glibc 是 Linux 系统中最基础的 C 运行库,提供了一系列底层 API,几乎所有其他运行库都依赖于它。本文详细介绍了 glibc 的主要功能和服务,并探讨了其在系统开发中的重要性。 ... [详细]
  • C#中实现高效UDP数据传输技术
    C#中实现高效UDP数据传输技术 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 如何尽量处理TIMEWAIT过多?
    如何尽量处理TIMEWAIT过多?编辑内核文件etcsysctl.conf,加入以下内容:net.ipv4.tcp_syncookies1表示开启SYNCookies。当出现SYN ... [详细]
author-avatar
陈陈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有