加载lua脚本的热更新探测

上一篇文章

c++与lua socket 高级调用
下面要进行热更新的文件调用,要做到更改lua文件时,重新启动脚本。这样不用重启c++服务。根据探测几种方式,最终认为使用libuv的文件监控比较简单,跨平台,QT也可以使用QT自身带的文件监控功能。

linux 文件监控

inotify,比较好用,和windowsapi类似

int inotify_init(void);
int inotify_add_watch(int fd, const char *pathname, uint32_t mask);
int inotify_rm_watch(int fd, uint32_t wd);

windows文件监控

可以使用windows 的api 来监控文件夹,ReadDirectoryChangesW ,主要代码如下所示

  HANDLE hDir; 
  char notify1024; 
  DWORD cbBytes,i; 
  char AnsiChar3; 
  wchar_t UnicodeChar2; 
  CString path;
 
  FILE_NOTIFY_INFORMATION *pnotify=(FILE_NOTIFY_INFORMATION *)notify; 
  FILE_NOTIFY_INFORMATION *tmp; 
 
  GetCurrentDirectory(MAX_PATH,path.GetBuffer(MAX_PATH+1));
  hDir = CreateFile( path, FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | 
    FILE_SHARE_WRITE | 
    FILE_SHARE_DELETE, NULL, 
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | 
    FILE_FLAG_OVERLAPPED, NULL); 
  if (hDir == INVALID_HANDLE_VALUE) 
   
 
    dlg->m_edit.ReplaceSel("hDir:INVALID_HANDLE_VALUE\r\n");
    return 0;
   
 
  while (TRUE) 
   {
    if(ReadDirectoryChangesW(hDir, ¬ify, sizeof(notify),
      FALSE, FILE_NOTIFY_CHANGE_FILE_NAME| FILE_NOTIFY_CHANGE_LAST_WRITE, 
      &cbBytes, NULL, NULL)) 
     
 
      tmp = pnotify; 
 
      switch(tmp->Action) 
       
      case FILE_ACTION_ADDED: 
 
        dlg->m_edit.ReplaceSel("Directory/File added (添加文件)- \r\n");
        break; 
      case FILE_ACTION_REMOVED:
        dlg->m_edit.ReplaceSel("Directory/File removed (删除文件)- \r\n");
        break; 
      case FILE_ACTION_MODIFIED: 
        dlg->m_edit.ReplaceSel("Directory/File modified (修改文件内容)- \r\n");
        break; 
      case FILE_ACTION_RENAMED_OLD_NAME: 
        dlg->m_edit.ReplaceSel("Directory/File old name (修改文件名字)- \r\n");
        break; 
      case FILE_ACTION_RENAMED_NEW_NAME: 
        dlg->m_edit.ReplaceSel("Directory/File new name - \r\n");
        break; 
      default: 
        break;
}

QT

QT可以使用QFileSystemWatcher* watcher 来监视文件,还是比较好用的

使用libuv

使用libuv的好处是跨平台,异步,非常好用,比QT的监控更加简单

#include <iostream>
#include <assert.h>
#include <stdio.h>
#include <fcntl.h>

#ifndef _WIN32
#include <unistd.h>
#endif
#include <uv.h>
#ifdef  _WIN32
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"psapi.lib")
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"Userenv.lib")
#endif



uv_loop_t* loop;
const char* command;

void run_command(uv_fs_event_t* handle, const char* filename, int events, int status) {
    char path[1024];
    size_t size = 1023;
    // Does not handle error if path is longer than 1023.
    uv_fs_event_getpath(handle, path, &size);
    path[size] = '\0';

    fprintf(stderr, "Change detected in %s: ", path);
    if (events & UV_RENAME)
        fprintf(stderr, "renamed");
    if (events & UV_CHANGE)
        fprintf(stderr, "changed");

    fprintf(stderr, " %s\n", filename ? filename : "");
   // system(command);
}

int main(int argc, char** argv) {

    loop = uv_default_loop();
    command = "dir";// argv[1];
    const char* file = "udp.lua";
  
        fprintf(stderr, "Adding watch on %s\n", file);
        uv_fs_event_t* fs_event_req = (uv_fs_event_t * )malloc(sizeof(uv_fs_event_t));
        uv_fs_event_init(loop, fs_event_req);
        // The recursive flag watches subdirectories too.
        uv_fs_event_start(fs_event_req, run_command,file , UV_FS_EVENT_RECURSIVE);
  
    return uv_run(loop, UV_RUN_DEFAULT);
}

以下为lua脚本

local socket = require("socket.core")
 local udp = socket.udp()
 local host = host or '127.0.0.1'
 local port = '6000'
 udp:settimeout(10)
 --local udpbind = udp:bind(host,port)
 udp:setsockname(host, port)
 print('waiting client connect')
 while 1 do
     local revbuff,receip,receport = udp:receivefrom()
     if (revbuff and receip and receport) then
         recv(revbuff)
     else
         print('waiting client connect-1')
     end
 end
 udp:close()

当我们修改lua脚本时
在这里插入图片描述
可以监控到文件改变,这时候可以停止lua运行,然后重启线程,做到热更新,这个下一次再实验。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qianbo_insist

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值