如何推送来自不同 class 的消息? (EE7 网络套接字)
How to push message from different class? (EE7 Websocket)
我已经使用 Java EE 7 提供的 API 为使用 HTML5 websockets 的游戏实现了一个 websocket 端点。我可以使用计时器任务成功发送消息以更新球的位置、砖块等,但我希望能够从我的游戏 class 中向正确的玩家发送消息,并在游戏输了,当比分更新时,...
现在对我来说唯一可行的方法是在每次更新时发送分数、amountOfLives……但我觉得这不是可行的方法。是否可以从不同的 classes 向客户端发送消息,在本例中是我的游戏 class?
游戏class(见评论我想达到什么)
public class Game implements Runnable {
private void loseLife() {
if (lives != 0) {
lives -= 1;
ball.reset(paddle);
} else {
lose();
}
}
private void lose() {
gameRunning = false;
// What I would like to achieve
sendMessage("Game is lost");
}
}
套接字端点:
@ServerEndpoint("/singleplayer")
public class SingleplayerSocket {
private static final Set<Session> PLAYERS = Collections.synchronizedSet(new HashSet<Session>());
private Session session;
private Gson gson;
private Game game;
private void sendMessage(String message) {
try {
for (Session player : PLAYERS) {
if (player == session) {
player.getBasicRemote().sendText(message);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
@OnOpen
public void onOpen(Session session) {
this.session = session;
PLAYERS.add(session);
sendMessage("Connection established");
}
@OnMessage
public void onMessage(String message) {
if (session != null && session.isOpen()) {
gson = new Gson();
String messageType = gson.fromJson(message, MessageType.class).getMessage();
switch (messageType) {
case "gameSetup":
String jsonData = getJsonData(message);
GameSetupRequest request = gson.fromJson(jsonData, GameSetupRequest.class);
int canvasWidth = request.getCanvasWidth();
int canvasHeight = request.getCanvasHeight();
String difficultyName = request.getDifficulty();
sendMessage(gameSetup(canvasWidth, canvasHeight, difficultyName));
break;
case "gameStart":
Thread gameLoop = new Thread(game);
gameLoop.start();
Timer timer = new Timer();
timer.schedule(new UpdateTask(), 0, 1000 / 60);
sendMessage("Game started");
break;
}
}
@OnClose
public void onClose(Session session) {
PLAYERS.remove(session);
this.session = null;
}
class UpdateTask extends TimerTask {
@Override
public void run() {
if (game.isGameRunning()) {
sendMessage(gameUpdate());
}
}
}
通过将会话添加到我的构造函数中解决了这个问题
private Session session;
public Game(Session session, int width, int height) {
this.session = session;
this.WIDTH = width;
this.HEIGHT = height;
}
private void sendMessage(String text) {
try {
session.getBasicRemote().sendText(text);
} catch (IOException e) {
e.printStackTrace();
}
}
然后像这样生成一个新游戏:
game = new Game(session, setupRequest.getCanvasWidth(), setupRequest.getCanvasHeight());
我已经使用 Java EE 7 提供的 API 为使用 HTML5 websockets 的游戏实现了一个 websocket 端点。我可以使用计时器任务成功发送消息以更新球的位置、砖块等,但我希望能够从我的游戏 class 中向正确的玩家发送消息,并在游戏输了,当比分更新时,...
现在对我来说唯一可行的方法是在每次更新时发送分数、amountOfLives……但我觉得这不是可行的方法。是否可以从不同的 classes 向客户端发送消息,在本例中是我的游戏 class?
游戏class(见评论我想达到什么)
public class Game implements Runnable {
private void loseLife() {
if (lives != 0) {
lives -= 1;
ball.reset(paddle);
} else {
lose();
}
}
private void lose() {
gameRunning = false;
// What I would like to achieve
sendMessage("Game is lost");
}
}
套接字端点:
@ServerEndpoint("/singleplayer")
public class SingleplayerSocket {
private static final Set<Session> PLAYERS = Collections.synchronizedSet(new HashSet<Session>());
private Session session;
private Gson gson;
private Game game;
private void sendMessage(String message) {
try {
for (Session player : PLAYERS) {
if (player == session) {
player.getBasicRemote().sendText(message);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
@OnOpen
public void onOpen(Session session) {
this.session = session;
PLAYERS.add(session);
sendMessage("Connection established");
}
@OnMessage
public void onMessage(String message) {
if (session != null && session.isOpen()) {
gson = new Gson();
String messageType = gson.fromJson(message, MessageType.class).getMessage();
switch (messageType) {
case "gameSetup":
String jsonData = getJsonData(message);
GameSetupRequest request = gson.fromJson(jsonData, GameSetupRequest.class);
int canvasWidth = request.getCanvasWidth();
int canvasHeight = request.getCanvasHeight();
String difficultyName = request.getDifficulty();
sendMessage(gameSetup(canvasWidth, canvasHeight, difficultyName));
break;
case "gameStart":
Thread gameLoop = new Thread(game);
gameLoop.start();
Timer timer = new Timer();
timer.schedule(new UpdateTask(), 0, 1000 / 60);
sendMessage("Game started");
break;
}
}
@OnClose
public void onClose(Session session) {
PLAYERS.remove(session);
this.session = null;
}
class UpdateTask extends TimerTask {
@Override
public void run() {
if (game.isGameRunning()) {
sendMessage(gameUpdate());
}
}
}
通过将会话添加到我的构造函数中解决了这个问题
private Session session;
public Game(Session session, int width, int height) {
this.session = session;
this.WIDTH = width;
this.HEIGHT = height;
}
private void sendMessage(String text) {
try {
session.getBasicRemote().sendText(text);
} catch (IOException e) {
e.printStackTrace();
}
}
然后像这样生成一个新游戏:
game = new Game(session, setupRequest.getCanvasWidth(), setupRequest.getCanvasHeight());