在Tomcat7.0.64下的examples文件夹内,有多人贪吃蛇的例子。
Multiplayer snake
这是一个多人在线小游戏,客户端通过操作上下左右键指挥自己的蛇,如果碰到别的蛇就死掉。还是一样,在服务端,对每个连接都维护一条蛇,有一个总的逻辑代码处理这些蛇,每条蛇再有各自的状态,向每个连接的客户发送消息。
![](https://images2015.cnblogs.com/blog/731200/201702/731200-20170210111329213-562621080.png)
1、@ServerEndpoint注解定义了一个WebSocket的访问路径,在Html页面中,通过ws开头的协议名称+项目地址+访问路径,即可建立WebSocket链接。
@ServerEndpoint创建的对象为非单例模式,每次建立WebSocket链接的时候,都会创建新的对象。
用两个浏览器打开该页面,生成的如下两个对象。
com.jiafuwei.java.snake.SnakeAnnotation@bda138
com.jiafuwei.java.snake.SnakeAnnotation@afca52
在这两个SnakeAnnotation对象中,通过@OnOpen注解会分别创建两个Snake对象
com.jiafuwei.java.snake.Snake@15b40dd
com.jiafuwei.java.snake.Snake@17e2247
生成的Snake对象分别会被各自的SnakeAnnotation对象维护,当我们在网页中触发上下左右移动的按钮时,会触发@OnMessage注解,从而改变Snake对象的方向,SnakeTimer定时任务每个0.1秒执行一次,向所有在线的浏览器广播所有蛇的位置,这样在线的蛇就位置就通过websocket同步了。
@ServerEndpoint(value = "/websocket/snake") public class SnakeAnnotation { private Snake snake; }
host = 'ws://' + window.location.host + '/Snake/websocket/snake'; if ('WebSocket' in window) { Game.socket = new WebSocket(host); } else if ('MozWebSocket' in window) { Game.socket = new MozWebSocket(host); } else { Console.log('Error: WebSocket is not supported by this browser.'); return; }
2、通过两个浏览器分别打开贪吃蛇的游戏页面,Html页面通过onopen方法触发后台的逻辑方法为@OnOpen注解
@OnOpen public void onOpen(Session session) { this.snake = new Snake(id, session); SnakeTimer.addSnake(snake); StringBuilder sb = new StringBuilder(); for (Iterator<Snake> iterator = SnakeTimer.getSnakes().iterator(); iterator.hasNext();) { Snake snake = iterator.next(); sb.append(String.format("{id: %d, color: '%s'}", Integer.valueOf(snake.getId()), snake.getHexColor())); if (iterator.hasNext()) { sb.append(','); } } SnakeTimer.broadcast(String.format("{'type': 'join','data':[%s]}", sb.toString())); }
Game.socket.onopen = function () { // Socket open.. start the game loop. Console.log('Info: WebSocket connection opened.'); Console.log('Info: Press an arrow key to begin.'); Game.startGameLoop(); setInterval(function() { // Prevent server read timeout. Game.socket.send('ping'); }, 5000); };