Pharo中能否部署多个ZnServer实例?遇静态文件服务报错求解
当然可以在同一个Pharo镜像里同时部署这两个服务,你遇到的错误主要是两个核心问题导致的——端口冲突,以及对ZnServer和委托的层次关系理解有误。
错误原因解析
- 端口冲突问题:你尝试在端口80上启动两个
ZnServer实例,这显然行不通,一个端口同一时间只能被一个服务占用。第二个ZnServer startOn: 80调用必然失败,这也不是多服务共存的正确姿势。 - 委托调用逻辑错误:错误提示
ZnStaticFileServerDelegate #doesNotUnderstand default delegate map,是因为你把ZnServer的方法(比如default delegate)错误用在了ZnStaticFileServerDelegate实例上。ZnStaticFileServerDelegate只是一个委托实现,它本身没有default或者map:这些属于服务器或默认委托的方法。
正确实现方案
我们只需要用一个ZnServer实例,通过「复合委托」或者「路径映射」的方式,把两个服务的逻辑整合在一起即可。
方案1:使用复合委托(ZnCompositeDelegate)
复合委托允许你把多个不同的委托组合起来,服务器会根据请求路径自动匹配对应的委托处理逻辑:
| server defaultDelegate staticDelegate compositeDelegate | server := ZnServer startOn: 80. "配置默认委托,处理你的WebRedirect逻辑" defaultDelegate := ZnDefaultServerDelegate new. defaultDelegate map: #display to: WebRedirect new. "配置静态文件服务器委托" staticDelegate := ZnStaticFileServerDelegate new directory: '/var/www' asFileReference; prefixFromString: 'files'; "访问路径前缀为/files" yourself. "组合两个委托" compositeDelegate := ZnCompositeDelegate new addDelegate: defaultDelegate; addDelegate: staticDelegate; yourself. "把复合委托设置给服务器" server delegate: compositeDelegate.
方案2:直接给默认委托添加静态文件路径映射
如果不需要独立的委托分离,也可以直接在ZnDefaultServerDelegate上添加静态文件的路径映射,实现更简洁:
| server delegate staticHandler | server := ZnServer startOn: 80. "初始化默认委托并添加你的重定向逻辑" delegate := ZnDefaultServerDelegate new. delegate map: #display to: WebRedirect new. "创建静态文件处理器,并映射到/files路径" staticHandler := ZnStaticFileServerDelegate new directory: '/var/www' asFileReference; yourself. delegate map: 'files' to: staticHandler. "设置服务器的委托" server delegate: delegate.
额外注意事项
- 确保
/var/www目录存在,并且Pharo进程有读取该目录的权限,否则静态文件服务会报错。 - 端口80属于系统特权端口,在Linux/macOS下可能需要用管理员权限运行Pharo(比如
sudo ./pharo),Windows下则需要以管理员身份启动Pharo。 - 测试阶段建议先用非特权端口(比如8080)验证功能正常,再切换到80端口。
内容的提问来源于stack exchange,提问作者rbsc
相关产品推荐
相关产品推荐

