如何在基于JPro的JavaFX Web应用中识别客户端用户?
解决JPro下JavaFX游戏引擎的客户端实例隔离与标识获取问题
核心思路
JPro的核心特性就是为每个Web客户端维护独立的JProSession,所有客户端专属的状态、实例都应该绑定到对应Session上,替代原来的全局单例模式,从根源解决实例共享问题。
具体实现步骤
改造全局单例为客户端专属实例
把原来的单例GameEngine类改成普通可实例化类,移除静态单例逻辑:class GameEngine { // 原有引擎逻辑,去掉object单例声明 fun update() { /* ... */ } // ...其他业务方法 }在客户端初始化时绑定实例到Session
在JPro应用的start方法中(每个客户端连接时都会触发这个方法),创建当前客户端专属的引擎实例,并存储到JProSession的属性中:class GameWebApp : JProApplication() { override fun start(stage: Stage) { val currentSession = JPro.getCurrentSession() // 创建当前客户端独有的引擎实例 val clientEngine = GameEngine() // 将实例绑定到Session,用唯一key标识 currentSession.setAttribute("client_game_engine", clientEngine) // 后续初始化UI、绑定事件等流程,直接使用这个clientEngine val gameScene = GameScene(clientEngine) stage.scene = Scene(gameScene, 800.0, 600.0) stage.show() } }在任意代码位置获取当前客户端的实例
封装一个工具方法,通过JPro.getCurrentSession()获取当前客户端的Session,再取出绑定的引擎实例:object EngineContext { fun getCurrentEngine(): GameEngine { val session = JPro.getCurrentSession() ?: throw IllegalStateException("当前不在JPro客户端上下文环境中") return session.getAttribute("client_game_engine") as GameEngine } }之后在任意业务代码中,直接调用
EngineContext.getCurrentEngine()就能拿到当前客户端的专属实例,比如:// 在某个UI组件的事件回调中 btnAttack.setOnAction { EngineContext.getCurrentEngine().playerAttack() }
关键注意事项
JPro.getCurrentSession()只能在客户端的JavaFX线程或者JPro的请求处理上下文中调用,如果在后台线程中需要获取,需要先通过Platform.runLater切换到UI线程,或者在初始化时把Session引用传递到后台任务中。- Session会在客户端断开连接时自动销毁,绑定的实例也会被回收,无需手动管理生命周期。
- 不要用全局静态变量存储任何客户端专属状态,所有状态都要通过Session关联,避免跨客户端污染。
内容的提问来源于stack exchange,提问作者Samuel Paradis
相关产品推荐
相关产品推荐

