Skynet 小试Debug_console...

    昨天凌晨4点还在写Skynet 服务试玩,结果发现自己写的服务出现内存泄漏了。

    今天早上起床吃早餐的时候一直在想:

    "如果每个Lua服务处理完客户端关闭的网络连接后,服务是否会自动退出呢?"

    答案:不会!

    现在,我们来看昨天写的Lua网络连接处理服务:

    首先是main.lua:

1local skynet = require "skynet" 2local socket = require "socket" 3 4 5 6skynet.start(function() 7 8 local id = socket.listen("192.168.2.5",80) 9 10 socket.start(id , function(fd,addr) 11 12 local cnn = skynet.newservice "network" 13 skynet.send(cnn,"lua","SOCKET",fd) 14 socket.abandon(fd) 15 16 end) 17 --skynet.exit() 18end)

    这里没什么问题,毕竟如果你skynet在start函数内退出,你监听的套接字也将被清空。

    然后是network.lua:

1local skynet = require "skynet" 2local socket = require "socket" 3 4skynet.init(function() 5 print("init was success...") 6end) 7 8local CMD = { } 9 10 11function CMD.SOCKET(fd) 12 13 socket.start(fd) 14 socket.write(fd,"welcome!\n\r>>") 15 16 while fd do 17 18 local buf = socket.readline(fd) 19 20 if buf and buf ~= "exit()" then 21 22 socket.write(fd,"you say: " .. buf .. "\r\n>>") 23 24 else 25 skynet.error("Client Closed this Connection...") 26 socket.close(fd) 27 break 28 end 29 end 30 31end 32 33skynet.start(function() 34 skynet.dispatch("lua",function(_,_,cmd,fd) 35 36 local f = assert(CMD[cmd]) 37 if f then 38 f(fd) 39 end 40 end) 41end)

    首先while语句开始,读取client 内容然后进入判断。

    然后socket阻塞连接并等待客户端数据。

    最后客户端关闭连接进入socket.close阶段,并且退出While循环。

    粗略一下没什么问题!但是细心的朋友可以看出,前面main文件在start方法内没调用skynet.exit就会一直存在。那我们怎么知道一个服务知否存在呢? 这就要靠debug_console了,我们简单修改一下main.lua文件,启动debug_console服务。

    修改后的main.lua文件如下:

1local skynet = require "skynet" 2local socket = require "socket" 3 4 5skynet.start(function() 6 skynet.newservice("debug_console",8000) -- 开启debug_console服务 7 local id = socket.listen("192.168.2.5",80) 8 socket.start(id,function(fd,ipaddr) 9 print(fd,ipaddr) 10 local cnn = skynet.newservice "network" 11 print(cnn) 12 skynet.send(cnn,"lua","SOCKET",fd) 13 socket.abandon(fd) 14 end) 15 16end)

    我在开始时,先启动debug_console服务并监听8000端口;然后我们使用telnet连接上去。

    

    这个"7 connected" 表示我们的console已经连接上了。

    

    然而我们的客户端还未进行连接,所以我们先list一下后发现network服务是没有启动;

    

    这时候,可以在cmd命令行内输入 telnet 192.168.2.5 80来发起一个客户端连接。

    

    好的,服务端已经进行了正确的回应。这时候我们在console 内再次进行list;

    

    network的lua服务已经启动并且接手管理socket连接相关处理,而我们的服务内只是简单完成了请求、回应相同数据的逻辑。

    这时候我们将client断开后再list会发现:network服务没有按照我预先想的那样自己退出。debug单步调试后也发现连接被close掉了。而此外你gc也仅仅只是进行lua代码的垃圾回收,而无法退出一个服务、

    

    至此,我们只能使用kill命令强行杀掉这个服务了。

    

    我们的lua服务必须在每个连接close后主动调用skynet.exit,否则一个隐式的内存泄漏将会产生。

    如果我们在一个万人在线的游戏服务器不小心犯了这个错误,每个用户只要重复登录5次,服务器的内存将会瞬间被吃光。

点赞
收藏

评论区

加载中...

相关推荐

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(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

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

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )