什么是世界频道?
"世界频道" 这个概念就是在一个游戏内经常见到。简单来说,世界频道就是在游戏内的一个大区中所有玩家可以接收、发布的消息的一个玩家间的统称。
玩家在游戏中进行体验的同时,通常需要发布一些特殊的消息,包含:"买卖装备、组队等";通常游戏中的各种频道的实现都依赖于消息队列的广播方式。
Skynet的组播解决了什么问题?
Skynet将消息通过指针进行传递到不同的服务之间,实现的简单的消息队列。当组播的消息较大时,可以节省内部网络的带宽。
下面直接上代码:
#Main:
local skynet = require "skynet"
local socket = require "socket"
skynet.start(function()
local id = socket.listen("192.168.2.5",80)
socket.start(id,function(fd,ipaddr)
local network = skynet.newservice "network"
skynet.send(network,"lua","Connection",fd,ipaddr)
socket.abandon(fd)
end)
end)
#network
local skynet = require "skynet"
local msg = require "multicast"
local socket = require "socket"
skynet.init(function()
-- 注册世界聊天频道
world_channel = skynet.uniqueservice "world_chat"
msg_fd = msg.new {
channel = skynet.call(world_channel,"lua","getMsgId"),
dispatch = get_subscribeMsg,
}
end)
local CMD = { }
function CMD.Connection(fd,ipaddr)
CMD.fd,CMD.ipaddr = fd,ipaddr
--print "订阅消息"
msg_fd:subscribe()
socket.start(fd)
socket.write(fd,"welcome!\n\r>>")
while fd do
local buf = socket.readline(fd)
if buf then
msg_fd:publish(buf)
else
skynet.error("Client Closed this Connection...")
break
end
end
socket.close(fd)
msg_fd:unsubscribe()
skynet.exit()
end
function get_subscribeMsg(channel,session,msg)
socket.write(CMD.fd,msg)
socket.write(CMD.fd,"\r\n>>")
end
skynet.start(function()
skynet.dispatch("lua",function(_,_,cmd,...)
local f = assert(CMD[cmd],"找不到指定的处理函数...")
if f then
f(...)
end
end)
end)
#world_chat
local skynet = require "skynet"
local msg = require "multicast"
local CMD = { }
skynet.init(function()
print "初始化世界频道...."
world_channel = msg.new()
end)
function CMD.getMsgId()
skynet.ret(skynet.pack(world_channel.channel))
end
skynet.start(function()
skynet.dispatch("lua",function(_,_,cmd,...)
local f = assert(CMD[cmd],"找不到指定的处理函数...")
if f then
f(...)
end
end)
end)
上述代码通过Skynet 的multicast实现了简单的世界聊天,在退出后关闭订阅。
而上述代码也存在两个问题。至于是什么问题?这个就留给大家自己思考了。:)