Skynet | echo服务
概述
引用云风博客的话:“skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。skynet 并不是一个开箱即用的引擎,使用它需要先对框架本身的结构有所了解,理解框架到底帮助开发者解决怎样的问题。如果你希望使用这个框架来开发网络游戏服务器,你将发现,skynet 并不会引导你把服务器搭建起来。它更像是一套工具,只有你知道你想做什么,它才会帮助你更有效率的完成。”
详情请参考:https://github.com/cloudwu/skynet/wiki/GettingStarted
下载 & 编译
安装环境:
- ubuntu16.04
- gcc5.4
- make 从github上下载
$ git clone https://github.com.cnpmjs.org/cloudwu/skynet.git
$ cd skynet && make linux
解析示例
启动一个服务端和客户端示例:
./skynet examples/config # Launch first skynet node (Gate server) and a skynet-master (see config for standalone option)
./3rd/lua/lua examples/client.lua # Launch a client, and try to input hello.
我是一个skynet小白,在我第一次看到官方示例的时候,只能看懂语法,但是不知道其中的逻辑关系。根据以往学习项目的经验,我先研究的怎么使用,然后再看源代码。在网上找到这个教程:https://blog.csdn.net/119365374/article/details/77790653, 写一个echo
,可以很好的理解skynet的使用。
写echo
服务的脚本
-- echo.lua
local skynet = require("skynet")
require ("skynet.manager")
local command = {<!-- -->}
function command.HELLO(what)
return "I am echo server: ".. what
end
skynet.start(function()
skynet.dispatch("lua", function(session, address, cmd, ...)
cmd = cmd:upper()
if cmd == "HELLO" then
local f = command[cmd]
assert(f)
skynet.ret(skynet.pack(f(...)))
end
end)
-- skynet.register("echo") --这句可以不要,已经验证过
end)
skynet.dispatch("lua", function(session, address, cmd, ...) end)
三个参数解释
- sesson: 请求序列号,是一个自增的id,溢出了又从1开始
- address:是skynet中服务的地址,这个地址在运行时是唯一的。在上面的代码中就是代表echo服务自已的地址。它实际上也是一个数字。
- cmd: 请求命令
调用echo
服务的test_echo.lua脚本
-- test_echo.lua
local skynet = require "skynet"
skynet.start(function ()
local echo = skynet.newservice("echo")
print(skynet.call(echo, "lua", "HELLO", "WORLD"))
end)
调用函数skynet.call(echo, "lua", "HELLO", "WORLD")
中四个参数的解释,
- echo: 调用服务的地址,与上面的address对应;
- HELLO: 请求命令,与上面的cmd对应;
- WORLD:请求参数;
- call是阻塞式调用。
写配置文件 examples/config.echo
-- config.echo
include "config.path"
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
thread = 8
logger = nil
logpath = "."
harbor = 1
address = "127.0.0.1:2526"
master = "127.0.0.1:2013"
start = "test_echo" -- 指定启动的脚本名字
bootstrap = "snlua bootstrap" -- The service for bootstrap
standalone = "0.0.0.0:2013"
-- snax_interface_g = "snax_g"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"
运行:
$ ./skynet examples/config.echo
这个例子让我们学习了skynet.start
、skynet.dispatch
、skynet.register
、skynet.call、skynet.newservice这几个重要的方法
改造成C/S架构的echo
了解了一下skynet的网络模型是actor模型,这样写起服务来更加得心应手了。
一个echo_server.lua
监听服务
local skynet = require "skynet"
local socket = require("skynet.socket")
local echo
function accept(id, addr)
print("accept connect from addr: ".. addr .. "; id: ".. id)
print(skynet.call(echo, "lua", "RWING", id))
end
skynet.start(function()
-- 读写的服务
echo = skynet.newservice("echo_rw")
-- 监听8883端口
local listen_id = socket.listen("0.0.0.0", 8883)
-- 开始监听
socket.start(listen_id, accept)
end)
读写服务 echo_rw.lua
local skynet = require("skynet")
local socket = require("skynet.socket")
require ("skynet.manager")
local command = {<!-- -->}
-- 这个函数才是 echo函数 接收客户端的数据,并且把数据原封不动的发回给客户端
function command.RWING(id)
print("start id: " .. id)
socket.start(id)
while true do
-- 读取客户端的数据
local msg = socket.read(id, nil)
if msg then
print("recv msg: ".. msg)
socket.write(id, msg)
else
socket.close(id)
return
end
end
end
skynet.start(function()
skynet.dispatch("lua", function(session, address, cmd, ...)
cmd = cmd:upper()
if cmd == "RWING" then
local f = command[cmd]
assert(f)
skynet.ret(skynet.pack(f(...))) --这个是模仿skynet例子里写的
end
end)
skynet.register("echo_rw")
end)
配置文件 config.echo
include "config.path"
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
thread = 8
logger = nil
logpath = "."
harbor = 1
address = "127.0.0.1:2526"
master = "127.0.0.1:2013"
start = "echo_server" -- echo_server script 主要是改 脚本名字
bootstrap = "snlua bootstrap" -- The service for bootstrap
standalone = "0.0.0.0:2013"
-- snax_interface_g = "snax_g"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"
启动
./skynet examples/config.echo
附上一个客户端测试一下服务器
package.cpath = "luaclib/?.so"
package.path = "lualib/?.lua;examples/?.lua"
if _VERSION ~= "Lua 5.4" then
error "Use lua 5.4"
end
local socket = require("client.socket")
local fd = assert(socket.connect("127.0.0.1", 8883))
local function sendpkg(fd, pack)
local package = string.pack(">s2", pack)
print("send msg: " .. package)
socket.send(fd, package)
end
local function recvpkg(fd)
local msg = socket.recv(fd)
if not msg then
return
end
if msg == "" then
return
end
print("recv from server msg: " .. msg)
end
function main()
sendpkg(fd, "hello world I'm Allen!!!") --发送消息
while true do
recvpkg(fd) --接收消息,写在循环里
end
end
main()
这是我入门skynet框架写的一个小demo,到这里就结束了,希望能对刚接触skynet的同学有所帮助。对了,skynet是使用actor作为通信模型,了解了actor之后可以更好的理解skynet。
参考连接:https://blog.csdn.net/119365374/article/details/77790653
--完--
- 原文作者: 留白
- 原文链接: https://zfunnily.github.io/2021/01/skynetecho/
- 更新时间:2024-04-16 01:01:05
- 本文声明:转载请标记原文作者及链接