学习记录四 运行skynet基础例子

0 创建自己的测试目录

 examples同级目录下创建  myexample文件夹,在里面添加study,study文件夹下添加config main.lua service1.lua socket1.lua

client.lua 文件。

1 config 文件,

config是启动skynet的必要配置文件,把example中的config内容整个复制过来添加注释,然后再稍作修改。

skynet会读取config文件获得启动参数,调用skynet-src/skynet_main.c脚本的入口main并传入config

完整代码如下:

root = "./" --根目录
thread = 8  --启动工作的线程数量,一般不要设置超过实际拥有的CPU核心数量
bootstrap = "snlua bootstrap"   -- 启动的第一个服务以及其启动参数 bootstrap 会根据luaservice匹配到lua脚本 默认是 :service/bootstrap.lua(其实第一个是logger)

logger = nil  --输出到标准输出
logpath = "."

harbor = 1 --1-255之间任意整数,一个skynet网络最多支持255个节点;0表示单节点模式,单节点模式下 后面三行不必设置
address = "127.0.0.1:2526" --当前skynet的地址和端口
master = "127.0.0.1:2013" --master配置项必须和standlone相同
standalone = "0.0.0.0:2013"

start = "main"  -- main script 设置bootstrap的最后一个节点(将要启动的lua服务)
luaservice = root.."service/?.lua;"..root.."myexample/study/?.lua"
lualoader = root .. "lualib/loader.lua"

lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"--将添加到package.path中的路径提供给require调用
lua_cpath = root .. "luaclib/?.so"--将添加到pachage.cpath 中的路径提供给require调用

snax = root.."example1/?.lua;"..root.."test/?.lua"
cpath = root.."cservice/?.so"  --cservice目录下的 .so 文件

应该非常清晰了,

2  simpledb.lua

service1的代码我是整个从官方 examples下的simpledb.lua 中拷贝过来进行测试的

 

部分api放在skynet.manager模块中,用到的时候如要引入skynet.manager模块。

skynet.launch   --启动launcher服务

skynet.kill  --杀掉一个服务(但无法杀掉死循环服务)

skynet.abort  --退出进程

skynet.register --注册别名(需要在32字符内)

skynet.name --给服务器命名

skynet. forward_type --将本服务实现为消息转发器,对一类消息进行转发

skynet.filter --过滤消息再处理

skynet.monitor --给当前skynet进程设置一个全局的服务监控

 

skynet的每个进程被称作一个skynet节点,

skynet.start  一个服务在lua层的入口

skynet.dispatch 注册特定类消息的处理函数

skynet.error 是lua-skynet.c#lerror 函数的别名 

skynet.ret  返回命令调用结果,所有通过ret的返回值都要用pack打包

  

service1完整代码如下

local skynet = require "skynet"--引入skynet库
require "skynet.manager"	  
local db = {}
local command = {}
--参考 examples simpledb.lua


function command.GET(key)
	-- body
	print("commant.get" .. key )
	return db[key]
end

function command.SET( key,value )
	-- body
	print("comman.set:key="..key..",value="..value)
	local last = db[key]
	db[key] = value
	
	return last
end

skynet.start(function ()
	-- body
	print("====== service1 start ======")
	skynet.dispatch("lua",function ( session,address,cmd,...)
		-- body
		cmd = cmd:upper()
		if cmd == "PING" then
			assert(session == 0)
			local str = (...)
			if #str > 20 then
				str = str:sub(1,20) .. "...(" .. #str .. ")"
			end
			skynet.error(string.format("%s ping %s", skynet.address(address), str))
			return
		end
		local f = command[cmd]
		if f then
			--
			skynet.ret(skynet.pack(f(...)))  --回应消息
		else
			error(string.format("Unknown command %s", tostring(cmd)))
		end
	end)
	skynet.register "SERVICE1"  --注册一个32字符内的别名
end)

 

3 main.lua

snlua服务模块:通过解析lua脚本来实现业务逻辑

cluster.reload

skynet.newservice

main完整代码如下:

local skynet = require "skynet"
local cluster = require "skynet.cluster"
local snax = require "skynet.snax"
skynet.start(function ()
	print("========== serverStart ==============")

	cluster.reload {
		db = "127.0.0.1:2527",
		db2 = "127.0.0.1:2528",
	}
	local service1 = skynet.newservice("service1") --启动lua服务

	--在内部生成一个唯一的session
	--把一类别为 typename的消息发送给address并阻塞等待对session的回应  
	--在 skynet.call 之前获得的服务内的状态,到返回后,很有可能改变
	skynet.call(service1,"lua","SET","a","footbar")

	-- --
	local kv = skynet.call(service1,"lua","GET","a")

	cluster.open "db"
	cluster.open "db2"

	-- skynet.newservice("socket1")
	skynet.exit()
end)

 

4 运行 执行命令

./skynet ./myexample/study/config

效果如下:

可以看到启动顺序,

snlua bootstrap 

snlua launcher

snlua cmaster 

实际上第一个启动的服务是logger ,第二个才是bootstrap 

bootstrap 是所有lua服务的标准启动入口,传入function参数, funtion方法也是此lua服务在lua层的回调接口,本服务的消息都在function回调方法中执行

snlua会把bootstrap作为参数传递给skynet 

snlua 是 lua 沙盒服务,bootstrap 会根据配置的 luaservice 匹配到最终的 lua 脚本。如果按默认配置,这个脚本应该是 service/bootstrap.lua 。

 

5 服务端与客户端的通信

编辑 socket1.lua    client.lua 两个

通讯时 官网提供 sproto 协议, skynet/lualib-src/sproto目录下可见(后面再看) 

client完整代码:

local skynetroot = "../skynet/"
package.cpath = skynetroot .. "luaclib/?.so"
package.path = skynetroot .. "lualib/?.lua;study/?.lua"

if _VERSION ~= "Lua 5.3" then
	error "[error use lua 5.3]"
end
local socket = require "client.socket"
local fd= assert(socket.connect("127.0.0.1",8800))
socket.send(fd,"hello skynet")--发送一条协议给服务器

socket1完整代码:

local skynet = require "skynet"
local socket = require "skynet.socket"

local function echo( id )
	-- body
	socket.start(id)
	while true do
		local str = socket.read(id)
		if str then
			print(str)
		else
			socket.close(id)
			return
		end
	end
end

skynet.start(function (  )
	-- body
	local id = socket.listen("127.0.0.1",8800)
	socket.start(id ,function ( id,addr )
		-- body
		print("connect from addr:" .. addr .. "id:" .. id)
		echo(id)
	end)
end)

运行服务器:把main.lua修改一下:

 

local skynet = require "skynet"
local cluster = require "skynet.cluster"
local snax = require "skynet.snax"
skynet.start(function ()
	print("========== serverStart ==============")

	-- cluster.reload {
	-- 	db = "127.0.0.1:2527",
	-- 	db2 = "127.0.0.1:2528",
	-- }
	-- local service1 = skynet.newservice("service1") --启动lua服务

	-- --在内部生成一个唯一的session
	-- --把一类别为 typename的消息发送给address并阻塞等待对session的回应  
	-- --在 skynet.call 之前获得的服务内的状态,到返回后,很有可能改变
	-- skynet.call(service1,"lua","SET","a","footbar")

	-- -- --
	-- local kv = skynet.call(service1,"lua","GET","a")

	-- cluster.open "db"
	-- cluster.open "db2"

	 skynet.newservice("socket1")
	 skynet.exit()
end)

启动服务:

./skynet ./myexample/study/config

启动 client 

./3rd/lua/lua ./myexample/study/client1.lua

这时服务端收到消息 hello skynet

然后是服务器响应消息 

在 socket1脚本文件的 echo中 添加 write

local function echo( id )
	socket.start(id)
	-- body
	while true do
		local str = socket.read(id)

		if str then
			print("server to client msg:" .. str)
			socket.write(id,str)
		else 
			socket.close(id)
		end
	end
end

然后在client脚本后添加代码

while true do
	local str = socket.recv(fd)
	if str~=nil and str~="" then
		print("server to client  msg :" .. str)
	end

	local readstr = socket.readstdin()
	if readstr then
		if readstr == "quit" then
			socket.close(fd)
			break;
		else 
			socket.send(fd,readstr)
		end
	else
		socket.usleep(100)
	end
end

和上面一样一次运行 server 和 client 这时候客户端打印出从服务端收到的消息  

 

参考:

          官方wiki:https://github.com/cloudwu/skynet/wiki/Sproto

           skynet分类api介绍 https://blog.csdn.net/lzb991435344/article/details/77216554

           skynet的luaAPI https://www.jianshu.com/p/9015bb091151

           skynet服务器框架:https://blog.csdn.net/linshuhe1/article/details/70174698 (超级详细 超级清晰)

            风云:https://blog.codingnow.com/2014/04/skynet_snax.html

码农聚集地qq群 199678137  欢迎大佬小白加入

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值