Skynet 通过组播(Multicast)实现一个简单的世界频道

什么是世界频道?

    "世界频道" 这个概念就是在一个游戏内经常见到。简单来说,世界频道就是在游戏内的一个大区中所有玩家可以接收、发布的消息的一个玩家间的统称。

    玩家在游戏中进行体验的同时,通常需要发布一些特殊的消息,包含:"买卖装备、组队等";通常游戏中的各种频道的实现都依赖于消息队列的广播方式。

Skynet的组播解决了什么问题?

    Skynet将消息通过指针进行传递到不同的服务之间,实现的简单的消息队列。当组播的消息较大时,可以节省内部网络的带宽。

下面直接上代码:

#Main:

1local skynet = require "skynet" 2local socket = require "socket" 3 4 5skynet.start(function() 6 local id = socket.listen("192.168.2.5",80) 7 socket.start(id,function(fd,ipaddr) 8 local network = skynet.newservice "network" 9 skynet.send(network,"lua","Connection",fd,ipaddr) 10 socket.abandon(fd) 11 end) 12 13 14end)

#network

1local skynet = require "skynet" 2local msg = require "multicast" 3local socket = require "socket" 4 5 6skynet.init(function() 7 8 -- 注册世界聊天频道 9 world_channel = skynet.uniqueservice "world_chat" 10 msg_fd = msg.new { 11 channel = skynet.call(world_channel,"lua","getMsgId"), 12 dispatch = get_subscribeMsg, 13 } 14 15end) 16 17 18local CMD = { } 19 20 21 22function CMD.Connection(fd,ipaddr) 23 CMD.fd,CMD.ipaddr = fd,ipaddr 24 --print "订阅消息" 25 msg_fd:subscribe() 26 socket.start(fd) 27 socket.write(fd,"welcome!\n\r>>") 28 while fd do 29 30 31 local buf = socket.readline(fd) 32 33 if buf then 34 35 msg_fd:publish(buf) 36 else 37 skynet.error("Client Closed this Connection...") 38 39 break 40 end 41 42 end 43 socket.close(fd) 44 msg_fd:unsubscribe() 45 skynet.exit() 46end 47 48 49function get_subscribeMsg(channel,session,msg) 50 socket.write(CMD.fd,msg) 51 socket.write(CMD.fd,"\r\n>>") 52end 53 54 55skynet.start(function() 56 skynet.dispatch("lua",function(_,_,cmd,...) 57 local f = assert(CMD[cmd],"找不到指定的处理函数...") 58 if f then 59 f(...) 60 end 61 end) 62end)

#world_chat

1local skynet = require "skynet" 2local msg = require "multicast" 3 4local CMD = { } 5 6 7skynet.init(function() 8 print "初始化世界频道...." 9 world_channel = msg.new() 10end) 11 12 13function CMD.getMsgId() 14 skynet.ret(skynet.pack(world_channel.channel)) 15end 16 17 18skynet.start(function() 19 skynet.dispatch("lua",function(_,_,cmd,...) 20 local f = assert(CMD[cmd],"找不到指定的处理函数...") 21 if f then 22 f(...) 23 end 24 end) 25end)

    上述代码通过Skynet 的multicast实现了简单的世界聊天,在退出后关闭订阅。

    而上述代码也存在两个问题。至于是什么问题?这个就留给大家自己思考了。:)

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

Redis 发布订阅

Redis发布订阅Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis客户端可以订阅任意数量的频道。下图展示了频道channel1,以及订阅这个频道的三个客户端——client2、client5和client1之间的关系:!(

Redis发布订阅

简介发布者和订阅者都是Redis客户端。发布者可以发消息到任意多个频道上,订阅者可以订阅任意多个频道。订阅命令subscribe channel\channel...\:返回的数字1,2表示订阅的第n个频道,频道返回的消息类型是message127.0.0.1:6379subscribeeduca

Java语言的Hook实现

<divid"blog\_content"class"blog\_content"<p引言:最近在玩完美时空的诛仙Online(不知道这里有没人有共同爱好的),这个游戏每晚七点会出现一个任务“新科试炼”。这个任务简单地说就是做选择题,范围小到柴米油盐,大到世界大千,所以多玩的YY上出现一个频道叫“诛仙答题频道”,这个频道会即时为玩家提供正确答案

Skynet 通过组播(Multicast)实现一个简单的世界频道 - HelloWorld