通过IDE菜单运行salix webApp时Webserver关闭失败端口占用问题求解
问题根因
你遇到的shutdown不可行非法参数错误,以及端口占用问题,核心由两个原因导致:
- 传入
util::Webserver::shutdown的参数格式不符合接口要求,该方法默认不接受带http协议前缀、末尾带斜杠的loc类型地址作为入参 - 未存储启动的Webserver实例,全局按地址检索运行中进程的匹配逻辑不稳定,很容易识别失败
可行解决方案
方案1:修改shutdown入参格式
最简单的修复方式是直接传入端口号作为shutdown的入参,大部分util::Webserver实现的shutdown方法原生支持端口号入参,修改后的代码如下:
void run_game(Tree t, loc s){ t = annotate(t); PSGAME g = ps_implode(t); Checker c = check_game(g); Engine engine = compile(c); loc host = |http://localhost:9050/|; // 直接传端口号调用shutdown try { util::Webserver::shutdown(9050);} catch: ; util::Webserver::serve(host, load_app(engine)().callback, asDaemon = true); println("Serving content at <host>"); }
如果还是报错,可以尝试把shutdown的入参换成不带协议和末尾斜杠的地址:|localhost:9050|。
方案2:全局存储Webserver实例(更稳定)
util::Webserver::serve方法会返回创建的Webserver实例,你可以在全局作用域存储这个实例,下次执行直接调用实例自身的shutdown方法,不会出现参数匹配错误的问题:
// 全局作用域新增变量,存储运行中的Webserver实例 private util::Webserver runningGameServer = null; void run_game(Tree t, loc s){ t = annotate(t); PSGAME g = ps_implode(t); Checker c = check_game(g); Engine engine = compile(c); loc host = |http://localhost:9050/|; // 关闭已存在的实例 if(runningGameServer != null) { try { runningGameServer.shutdown(); runningGameServer = null; } catch: {} } // 启动新实例并存入全局变量 runningGameServer = util::Webserver::serve(host, load_app(engine)().callback, asDaemon = true); println("Serving content at <host>"); }
该方案不需要修改原有注册逻辑,稳定性远高于全局检索关闭的方式。
方案3:使用热重载替代重启(体验最优)
你完全不需要每次执行都重启Webserver,只需要用代理回调动态替换业务逻辑即可,首次启动后后续执行只更新回调内容,不会有端口占用问题,刷新浏览器就能看到更新,响应速度更快:
// 全局存储Webserver实例和当前生效的业务回调 private util::Webserver gameServer = null; private Function latestGameCallback = null; void run_game(Tree t, loc s){ t = annotate(t); PSGAME g = ps_implode(t); Checker c = check_game(g); Engine engine = compile(c); loc host = |http://localhost:9050/|; // 更新最新的业务回调 latestGameCallback = load_app(engine)().callback; // 首次执行才启动Webserver,后续直接复用 if(gameServer == null) { // 代理回调,每次请求都调用最新的业务逻辑 gameServer = util::Webserver::serve(host, (req) -> latestGameCallback(req), asDaemon = true); } println("Serving content at <host>,刷新浏览器即可查看更新"); }
内容的提问来源于stack exchange,提问作者Clement Julia
相关产品推荐
相关产品推荐

