Commit 1a9ce42d authored by Phillip Webb's avatar Phillip Webb

Apply source formatting to samples

parent efe102bd
...@@ -48,6 +48,26 @@ ...@@ -48,6 +48,26 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<useProjectReferences>false</useProjectReferences>
<additionalConfig>
<file>
<name>.settings/org.eclipse.jdt.ui.prefs</name>
<location>${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs</location>
</file>
<file>
<name>.settings/org.eclipse.jdt.core.prefs</name>
<location>${main.basedir}/eclipse/org.eclipse.jdt.core.prefs</location>
</file>
</additionalConfig>
</configuration>
</plugin>
</plugins>
</build>
<repositories> <repositories>
<repository> <repository>
<id>spring-snapshots</id> <id>spring-snapshots</id>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<version>0.5.0.BUILD-SNAPSHOT</version> <version>0.5.0.BUILD-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>
<main.basedir>${basedir}/../..</main.basedir>
<java.version>1.7</java.version> <java.version>1.7</java.version>
<tomcat.version>8.0.0-RC3</tomcat.version> <tomcat.version>8.0.0-RC3</tomcat.version>
</properties> </properties>
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.client; package org.springframework.boot.samples.websocket.client;
public interface GreetingService { public interface GreetingService {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.client; package org.springframework.boot.samples.websocket.client;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
...@@ -33,7 +34,8 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandlerAdapter { ...@@ -33,7 +34,8 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandlerAdapter {
private CountDownLatch latch; private CountDownLatch latch;
@Autowired @Autowired
public SimpleClientWebSocketHandler(GreetingService greetingService, CountDownLatch latch) { public SimpleClientWebSocketHandler(GreetingService greetingService,
CountDownLatch latch) {
this.greetingService = greetingService; this.greetingService = greetingService;
this.latch = latch; this.latch = latch;
} }
...@@ -45,10 +47,11 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandlerAdapter { ...@@ -45,10 +47,11 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandlerAdapter {
} }
@Override @Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { public void handleTextMessage(WebSocketSession session, TextMessage message)
logger.info("Received: " + message + " (" + latch.getCount() + ")"); throws Exception {
this.logger.info("Received: " + message + " (" + this.latch.getCount() + ")");
session.close(); session.close();
latch.countDown(); this.latch.countDown();
} }
} }
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.client; package org.springframework.boot.samples.websocket.client;
public class SimpleGreetingService implements GreetingService { public class SimpleGreetingService implements GreetingService {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.echo; package org.springframework.boot.samples.websocket.echo;
public class DefaultEchoService implements EchoService { public class DefaultEchoService implements EchoService {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.echo; package org.springframework.boot.samples.websocket.echo;
public interface EchoService { public interface EchoService {
......
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.samples.websocket.echo; package org.springframework.boot.samples.websocket.echo;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -29,14 +45,16 @@ public class EchoWebSocketHandler extends TextWebSocketHandlerAdapter { ...@@ -29,14 +45,16 @@ public class EchoWebSocketHandler extends TextWebSocketHandlerAdapter {
} }
@Override @Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { public void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
String echoMessage = this.echoService.getMessage(message.getPayload()); String echoMessage = this.echoService.getMessage(message.getPayload());
logger.debug(echoMessage); logger.debug(echoMessage);
session.sendMessage(new TextMessage(echoMessage)); session.sendMessage(new TextMessage(echoMessage));
} }
@Override @Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { public void handleTransportError(WebSocketSession session, Throwable exception)
throws Exception {
session.close(CloseStatus.SERVER_ERROR); session.close(CloseStatus.SERVER_ERROR);
} }
......
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake; package org.springframework.boot.samples.websocket.snake;
public enum Direction { public enum Direction {
NONE, NORTH, SOUTH, EAST, WEST NONE, NORTH, SOUTH, EAST, WEST
} }
...@@ -14,58 +14,60 @@ ...@@ -14,58 +14,60 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake;
import org.springframework.boot.samples.websocket.snake.Direction;
package org.springframework.boot.samples.websocket.snake;
public class Location { public class Location {
public int x; public int x;
public int y; public int y;
public static final int GRID_SIZE = 10; public static final int GRID_SIZE = 10;
public static final int PLAYFIELD_HEIGHT = 480; public static final int PLAYFIELD_HEIGHT = 480;
public static final int PLAYFIELD_WIDTH = 640; public static final int PLAYFIELD_WIDTH = 640;
public Location(int x, int y) { public Location(int x, int y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
public Location getAdjacentLocation(Direction direction) { public Location getAdjacentLocation(Direction direction) {
switch (direction) { switch (direction) {
case NORTH: case NORTH:
return new Location(x, y - Location.GRID_SIZE); return new Location(this.x, this.y - Location.GRID_SIZE);
case SOUTH: case SOUTH:
return new Location(x, y + Location.GRID_SIZE); return new Location(this.x, this.y + Location.GRID_SIZE);
case EAST: case EAST:
return new Location(x + Location.GRID_SIZE, y); return new Location(this.x + Location.GRID_SIZE, this.y);
case WEST: case WEST:
return new Location(x - Location.GRID_SIZE, y); return new Location(this.x - Location.GRID_SIZE, this.y);
case NONE: case NONE:
// fall through // fall through
default: default:
return this; return this;
} }
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o)
if (o == null || getClass() != o.getClass()) return false; return true;
if (o == null || getClass() != o.getClass())
return false;
Location location = (Location) o; Location location = (Location) o;
if (x != location.x) return false; if (this.x != location.x)
if (y != location.y) return false; return false;
if (this.y != location.y)
return false;
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = x; int result = this.x;
result = 31 * result + y; result = 31 * result + this.y;
return result; return result;
} }
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake; package org.springframework.boot.samples.websocket.snake;
import java.util.ArrayDeque; import java.util.ArrayDeque;
...@@ -23,117 +24,116 @@ import java.util.Deque; ...@@ -23,117 +24,116 @@ import java.util.Deque;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
public class Snake { public class Snake {
private static final int DEFAULT_LENGTH = 5; private static final int DEFAULT_LENGTH = 5;
private final int id; private final int id;
private final WebSocketSession session; private final WebSocketSession session;
private Direction direction; private Direction direction;
private int length = DEFAULT_LENGTH; private int length = DEFAULT_LENGTH;
private Location head; private Location head;
private final Deque<Location> tail = new ArrayDeque<Location>(); private final Deque<Location> tail = new ArrayDeque<Location>();
private final String hexColor; private final String hexColor;
public Snake(int id, WebSocketSession session) { public Snake(int id, WebSocketSession session) {
this.id = id; this.id = id;
this.session = session; this.session = session;
this.hexColor = SnakeUtils.getRandomHexColor(); this.hexColor = SnakeUtils.getRandomHexColor();
resetState(); resetState();
} }
private void resetState() { private void resetState() {
this.direction = Direction.NONE; this.direction = Direction.NONE;
this.head = SnakeUtils.getRandomLocation(); this.head = SnakeUtils.getRandomLocation();
this.tail.clear(); this.tail.clear();
this.length = DEFAULT_LENGTH; this.length = DEFAULT_LENGTH;
} }
private synchronized void kill() throws Exception { private synchronized void kill() throws Exception {
resetState(); resetState();
sendMessage("{'type': 'dead'}"); sendMessage("{'type': 'dead'}");
} }
private synchronized void reward() throws Exception { private synchronized void reward() throws Exception {
length++; this.length++;
sendMessage("{'type': 'kill'}"); sendMessage("{'type': 'kill'}");
} }
protected void sendMessage(String msg) throws Exception {
protected void sendMessage(String msg) throws Exception { this.session.sendMessage(new TextMessage(msg));
session.sendMessage(new TextMessage(msg)); }
}
public synchronized void update(Collection<Snake> snakes) throws Exception {
public synchronized void update(Collection<Snake> snakes) throws Exception { Location nextLocation = this.head.getAdjacentLocation(this.direction);
Location nextLocation = head.getAdjacentLocation(direction); if (nextLocation.x >= SnakeUtils.PLAYFIELD_WIDTH) {
if (nextLocation.x >= SnakeUtils.PLAYFIELD_WIDTH) { nextLocation.x = 0;
nextLocation.x = 0; }
} if (nextLocation.y >= SnakeUtils.PLAYFIELD_HEIGHT) {
if (nextLocation.y >= SnakeUtils.PLAYFIELD_HEIGHT) { nextLocation.y = 0;
nextLocation.y = 0; }
} if (nextLocation.x < 0) {
if (nextLocation.x < 0) { nextLocation.x = SnakeUtils.PLAYFIELD_WIDTH;
nextLocation.x = SnakeUtils.PLAYFIELD_WIDTH; }
} if (nextLocation.y < 0) {
if (nextLocation.y < 0) { nextLocation.y = SnakeUtils.PLAYFIELD_HEIGHT;
nextLocation.y = SnakeUtils.PLAYFIELD_HEIGHT; }
} if (this.direction != Direction.NONE) {
if (direction != Direction.NONE) { this.tail.addFirst(this.head);
tail.addFirst(head); if (this.tail.size() > this.length) {
if (tail.size() > length) { this.tail.removeLast();
tail.removeLast(); }
} this.head = nextLocation;
head = nextLocation; }
}
handleCollisions(snakes);
handleCollisions(snakes); }
}
private void handleCollisions(Collection<Snake> snakes) throws Exception {
private void handleCollisions(Collection<Snake> snakes) throws Exception { for (Snake snake : snakes) {
for (Snake snake : snakes) { boolean headCollision = this.id != snake.id
boolean headCollision = id != snake.id && snake.getHead().equals(head); && snake.getHead().equals(this.head);
boolean tailCollision = snake.getTail().contains(head); boolean tailCollision = snake.getTail().contains(this.head);
if (headCollision || tailCollision) { if (headCollision || tailCollision) {
kill(); kill();
if (id != snake.id) { if (this.id != snake.id) {
snake.reward(); snake.reward();
} }
} }
} }
} }
public synchronized Location getHead() { public synchronized Location getHead() {
return head; return this.head;
} }
public synchronized Collection<Location> getTail() { public synchronized Collection<Location> getTail() {
return tail; return this.tail;
} }
public synchronized void setDirection(Direction direction) { public synchronized void setDirection(Direction direction) {
this.direction = direction; this.direction = direction;
} }
public synchronized String getLocationsJson() { public synchronized String getLocationsJson() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(String.format("{x: %d, y: %d}", sb.append(String.format("{x: %d, y: %d}", Integer.valueOf(this.head.x),
Integer.valueOf(head.x), Integer.valueOf(head.y))); Integer.valueOf(this.head.y)));
for (Location location : tail) { for (Location location : this.tail) {
sb.append(','); sb.append(',');
sb.append(String.format("{x: %d, y: %d}", sb.append(String.format("{x: %d, y: %d}", Integer.valueOf(location.x),
Integer.valueOf(location.x), Integer.valueOf(location.y))); Integer.valueOf(location.y)));
} }
return String.format("{'id':%d,'body':[%s]}", return String.format("{'id':%d,'body':[%s]}", Integer.valueOf(this.id),
Integer.valueOf(id), sb.toString()); sb.toString());
} }
public int getId() { public int getId() {
return id; return this.id;
} }
public String getHexColor() { public String getHexColor() {
return hexColor; return this.hexColor;
} }
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake; package org.springframework.boot.samples.websocket.snake;
import java.util.Collection; import java.util.Collection;
...@@ -32,84 +33,77 @@ import org.apache.juli.logging.LogFactory; ...@@ -32,84 +33,77 @@ import org.apache.juli.logging.LogFactory;
*/ */
public class SnakeTimer { public class SnakeTimer {
private static final Log log = private static final Log log = LogFactory.getLog(SnakeTimer.class);
LogFactory.getLog(SnakeTimer.class);
private static Timer gameTimer = null;
private static Timer gameTimer = null;
private static final long TICK_DELAY = 100;
private static final long TICK_DELAY = 100;
private static final ConcurrentHashMap<Integer, Snake> snakes = new ConcurrentHashMap<Integer, Snake>();
private static final ConcurrentHashMap<Integer, Snake> snakes =
new ConcurrentHashMap<Integer, Snake>(); public static synchronized void addSnake(Snake snake) {
if (snakes.size() == 0) {
public static synchronized void addSnake(Snake snake) { startTimer();
if (snakes.size() == 0) { }
startTimer(); snakes.put(Integer.valueOf(snake.getId()), snake);
} }
snakes.put(Integer.valueOf(snake.getId()), snake);
} public static Collection<Snake> getSnakes() {
return Collections.unmodifiableCollection(snakes.values());
}
public static Collection<Snake> getSnakes() {
return Collections.unmodifiableCollection(snakes.values()); public static synchronized void removeSnake(Snake snake) {
} snakes.remove(Integer.valueOf(snake.getId()));
if (snakes.size() == 0) {
stopTimer();
public static synchronized void removeSnake(Snake snake) { }
snakes.remove(Integer.valueOf(snake.getId())); }
if (snakes.size() == 0) {
stopTimer(); public static void tick() throws Exception {
} StringBuilder sb = new StringBuilder();
} for (Iterator<Snake> iterator = SnakeTimer.getSnakes().iterator(); iterator
.hasNext();) {
Snake snake = iterator.next();
public static void tick() throws Exception { snake.update(SnakeTimer.getSnakes());
StringBuilder sb = new StringBuilder(); sb.append(snake.getLocationsJson());
for (Iterator<Snake> iterator = SnakeTimer.getSnakes().iterator(); if (iterator.hasNext()) {
iterator.hasNext();) { sb.append(',');
Snake snake = iterator.next(); }
snake.update(SnakeTimer.getSnakes()); }
sb.append(snake.getLocationsJson()); broadcast(String.format("{'type': 'update', 'data' : [%s]}", sb.toString()));
if (iterator.hasNext()) { }
sb.append(',');
} public static void broadcast(String message) throws Exception {
} Collection<Snake> snakes = new CopyOnWriteArrayList<>(SnakeTimer.getSnakes());
broadcast(String.format("{'type': 'update', 'data' : [%s]}", for (Snake snake : snakes) {
sb.toString())); try {
} snake.sendMessage(message);
}
public static void broadcast(String message) throws Exception { catch (Throwable ex) {
Collection<Snake> snakes = new CopyOnWriteArrayList<>(SnakeTimer.getSnakes()); // if Snake#sendMessage fails the client is removed
for (Snake snake : snakes) { removeSnake(snake);
try { }
snake.sendMessage(message); }
} }
catch (Throwable ex) {
// if Snake#sendMessage fails the client is removed public static void startTimer() {
removeSnake(snake); gameTimer = new Timer(SnakeTimer.class.getSimpleName() + " Timer");
} gameTimer.scheduleAtFixedRate(new TimerTask() {
} @Override
} public void run() {
try {
tick();
public static void startTimer() { }
gameTimer = new Timer(SnakeTimer.class.getSimpleName() + " Timer"); catch (Throwable e) {
gameTimer.scheduleAtFixedRate(new TimerTask() { log.error("Caught to prevent timer from shutting down", e);
@Override }
public void run() { }
try { }, TICK_DELAY, TICK_DELAY);
tick(); }
} catch (Throwable e) {
log.error("Caught to prevent timer from shutting down", e); public static void stopTimer() {
} if (gameTimer != null) {
} gameTimer.cancel();
}, TICK_DELAY, TICK_DELAY); }
} }
public static void stopTimer() {
if (gameTimer != null) {
gameTimer.cancel();
}
}
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake; package org.springframework.boot.samples.websocket.snake;
import java.awt.Color; import java.awt.Color;
...@@ -21,36 +22,33 @@ import java.util.Random; ...@@ -21,36 +22,33 @@ import java.util.Random;
public class SnakeUtils { public class SnakeUtils {
public static final int PLAYFIELD_WIDTH = 640; public static final int PLAYFIELD_WIDTH = 640;
public static final int PLAYFIELD_HEIGHT = 480; public static final int PLAYFIELD_HEIGHT = 480;
public static final int GRID_SIZE = 10; public static final int GRID_SIZE = 10;
private static final Random random = new Random(); private static final Random random = new Random();
public static String getRandomHexColor() {
public static String getRandomHexColor() { float hue = random.nextFloat();
float hue = random.nextFloat(); // sat between 0.1 and 0.3
// sat between 0.1 and 0.3 float saturation = (random.nextInt(2000) + 1000) / 10000f;
float saturation = (random.nextInt(2000) + 1000) / 10000f; float luminance = 0.9f;
float luminance = 0.9f; Color color = Color.getHSBColor(hue, saturation, luminance);
Color color = Color.getHSBColor(hue, saturation, luminance); return '#' + Integer.toHexString((color.getRGB() & 0xffffff) | 0x1000000)
return '#' + Integer.toHexString( .substring(1);
(color.getRGB() & 0xffffff) | 0x1000000).substring(1); }
}
public static Location getRandomLocation() {
int x = roundByGridSize(random.nextInt(PLAYFIELD_WIDTH));
public static Location getRandomLocation() { int y = roundByGridSize(random.nextInt(PLAYFIELD_HEIGHT));
int x = roundByGridSize(random.nextInt(PLAYFIELD_WIDTH)); return new Location(x, y);
int y = roundByGridSize(random.nextInt(PLAYFIELD_HEIGHT)); }
return new Location(x, y);
} private static int roundByGridSize(int value) {
value = value + (GRID_SIZE / 2);
value = value / GRID_SIZE;
private static int roundByGridSize(int value) { value = value * GRID_SIZE;
value = value + (GRID_SIZE / 2); return value;
value = value / GRID_SIZE; }
value = value * GRID_SIZE;
return value;
}
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.snake; package org.springframework.boot.samples.websocket.snake;
import java.awt.Color; import java.awt.Color;
...@@ -28,85 +29,84 @@ import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter; ...@@ -28,85 +29,84 @@ import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter;
public class SnakeWebSocketHandler extends TextWebSocketHandlerAdapter { public class SnakeWebSocketHandler extends TextWebSocketHandlerAdapter {
public static final int PLAYFIELD_WIDTH = 640; public static final int PLAYFIELD_WIDTH = 640;
public static final int PLAYFIELD_HEIGHT = 480; public static final int PLAYFIELD_HEIGHT = 480;
public static final int GRID_SIZE = 10; public static final int GRID_SIZE = 10;
private static final AtomicInteger snakeIds = new AtomicInteger(0); private static final AtomicInteger snakeIds = new AtomicInteger(0);
private static final Random random = new Random(); private static final Random random = new Random();
private final int id;
private final int id; private Snake snake;
private Snake snake;
public static String getRandomHexColor() {
public static String getRandomHexColor() { float hue = random.nextFloat();
float hue = random.nextFloat(); // sat between 0.1 and 0.3
// sat between 0.1 and 0.3 float saturation = (random.nextInt(2000) + 1000) / 10000f;
float saturation = (random.nextInt(2000) + 1000) / 10000f; float luminance = 0.9f;
float luminance = 0.9f; Color color = Color.getHSBColor(hue, saturation, luminance);
Color color = Color.getHSBColor(hue, saturation, luminance); return '#' + Integer.toHexString((color.getRGB() & 0xffffff) | 0x1000000)
return '#' + Integer.toHexString( .substring(1);
(color.getRGB() & 0xffffff) | 0x1000000).substring(1); }
}
public static Location getRandomLocation() {
int x = roundByGridSize(random.nextInt(PLAYFIELD_WIDTH));
public static Location getRandomLocation() { int y = roundByGridSize(random.nextInt(PLAYFIELD_HEIGHT));
int x = roundByGridSize(random.nextInt(PLAYFIELD_WIDTH)); return new Location(x, y);
int y = roundByGridSize(random.nextInt(PLAYFIELD_HEIGHT)); }
return new Location(x, y);
} private static int roundByGridSize(int value) {
value = value + (GRID_SIZE / 2);
value = value / GRID_SIZE;
private static int roundByGridSize(int value) { value = value * GRID_SIZE;
value = value + (GRID_SIZE / 2); return value;
value = value / GRID_SIZE; }
value = value * GRID_SIZE;
return value; public SnakeWebSocketHandler() {
} this.id = snakeIds.getAndIncrement();
}
public SnakeWebSocketHandler() {
this.id = snakeIds.getAndIncrement(); @Override
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception { public void afterConnectionEstablished(WebSocketSession session) throws Exception {
this.snake = new Snake(id, session); this.snake = new Snake(this.id, session);
SnakeTimer.addSnake(snake); SnakeTimer.addSnake(this.snake);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Iterator<Snake> iterator = SnakeTimer.getSnakes().iterator(); for (Iterator<Snake> iterator = SnakeTimer.getSnakes().iterator(); iterator
iterator.hasNext();) { .hasNext();) {
Snake snake = iterator.next(); Snake snake = iterator.next();
sb.append(String.format("{id: %d, color: '%s'}", sb.append(String.format("{id: %d, color: '%s'}",
Integer.valueOf(snake.getId()), snake.getHexColor())); Integer.valueOf(snake.getId()), snake.getHexColor()));
if (iterator.hasNext()) { if (iterator.hasNext()) {
sb.append(','); sb.append(',');
} }
} }
SnakeTimer.broadcast(String.format("{'type': 'join','data':[%s]}", SnakeTimer
sb.toString())); .broadcast(String.format("{'type': 'join','data':[%s]}", sb.toString()));
} }
@Override
@Override protected void handleTextMessage(WebSocketSession session, TextMessage message)
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { throws Exception {
String payload = message.getPayload(); String payload = message.getPayload();
if ("west".equals(payload)) { if ("west".equals(payload)) {
snake.setDirection(Direction.WEST); this.snake.setDirection(Direction.WEST);
} else if ("north".equals(payload)) { }
snake.setDirection(Direction.NORTH); else if ("north".equals(payload)) {
} else if ("east".equals(payload)) { this.snake.setDirection(Direction.NORTH);
snake.setDirection(Direction.EAST); }
} else if ("south".equals(payload)) { else if ("east".equals(payload)) {
snake.setDirection(Direction.SOUTH); this.snake.setDirection(Direction.EAST);
} }
} else if ("south".equals(payload)) {
this.snake.setDirection(Direction.SOUTH);
}
@Override }
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
SnakeTimer.removeSnake(snake); @Override
SnakeTimer.broadcast(String.format("{'type': 'leave', 'id': %d}", public void afterConnectionClosed(WebSocketSession session, CloseStatus status)
Integer.valueOf(id))); throws Exception {
} SnakeTimer.removeSnake(this.snake);
SnakeTimer.broadcast(String.format("{'type': 'leave', 'id': %d}",
Integer.valueOf(this.id)));
}
} }
...@@ -13,9 +13,8 @@ ...@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.samples.websocket.echo;
import static org.junit.Assert.assertEquals; package org.springframework.boot.samples.websocket.echo;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
...@@ -40,6 +39,8 @@ import org.springframework.context.annotation.Configuration; ...@@ -40,6 +39,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.client.WebSocketConnectionManager; import org.springframework.web.socket.client.WebSocketConnectionManager;
import org.springframework.web.socket.client.endpoint.StandardWebSocketClient; import org.springframework.web.socket.client.endpoint.StandardWebSocketClient;
import static org.junit.Assert.assertEquals;
public class SampleWebSocketsApplicationTests { public class SampleWebSocketsApplicationTests {
private static Log logger = LogFactory.getLog(SampleWebSocketsApplicationTests.class); private static Log logger = LogFactory.getLog(SampleWebSocketsApplicationTests.class);
...@@ -55,7 +56,7 @@ public class SampleWebSocketsApplicationTests { ...@@ -55,7 +56,7 @@ public class SampleWebSocketsApplicationTests {
new Callable<ConfigurableApplicationContext>() { new Callable<ConfigurableApplicationContext>() {
@Override @Override
public ConfigurableApplicationContext call() throws Exception { public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication return SpringApplication
.run(SampleWebSocketsApplication.class); .run(SampleWebSocketsApplication.class);
} }
}); });
...@@ -71,7 +72,8 @@ public class SampleWebSocketsApplicationTests { ...@@ -71,7 +72,8 @@ public class SampleWebSocketsApplicationTests {
@Test @Test
public void runAndWait() throws Exception { public void runAndWait() throws Exception {
ConfigurableApplicationContext context = (ConfigurableApplicationContext) SpringApplication.run(ClientConfiguration.class, "--spring.main.web_environment=false"); ConfigurableApplicationContext context = SpringApplication.run(
ClientConfiguration.class, "--spring.main.web_environment=false");
long count = context.getBean(ClientConfiguration.class).latch.getCount(); long count = context.getBean(ClientConfiguration.class).latch.getCount();
context.close(); context.close();
assertEquals(0, count); assertEquals(0, count);
...@@ -84,15 +86,16 @@ public class SampleWebSocketsApplicationTests { ...@@ -84,15 +86,16 @@ public class SampleWebSocketsApplicationTests {
@Override @Override
public void run(String... args) throws Exception { public void run(String... args) throws Exception {
logger.info("Waiting for response: latch=" + latch.getCount()); logger.info("Waiting for response: latch=" + this.latch.getCount());
latch.await(10, TimeUnit.SECONDS); this.latch.await(10, TimeUnit.SECONDS);
logger.info("Got response: latch=" + latch.getCount()); logger.info("Got response: latch=" + this.latch.getCount());
} }
@Bean @Bean
public WebSocketConnectionManager wsConnectionManager() { public WebSocketConnectionManager wsConnectionManager() {
WebSocketConnectionManager manager = new WebSocketConnectionManager(client(), handler(), WS_URI); WebSocketConnectionManager manager = new WebSocketConnectionManager(client(),
handler(), WS_URI);
manager.setAutoStartup(true); manager.setAutoStartup(true);
return manager; return manager;
...@@ -105,7 +108,7 @@ public class SampleWebSocketsApplicationTests { ...@@ -105,7 +108,7 @@ public class SampleWebSocketsApplicationTests {
@Bean @Bean
public SimpleClientWebSocketHandler handler() { public SimpleClientWebSocketHandler handler() {
return new SimpleClientWebSocketHandler(greetingService(), latch); return new SimpleClientWebSocketHandler(greetingService(), this.latch);
} }
@Bean @Bean
......
package org.springframework.boot.samples.websocket.snake; /*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.junit.Test; package org.springframework.boot.samples.websocket.snake;
import java.io.IOException; import java.io.IOException;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
...@@ -12,13 +28,13 @@ import static org.mockito.Mockito.mock; ...@@ -12,13 +28,13 @@ import static org.mockito.Mockito.mock;
public class SnakeTimerTests { public class SnakeTimerTests {
@Test @Test
public void removeDysfunctionalSnakes() throws Exception { public void removeDysfunctionalSnakes() throws Exception {
Snake snake = mock(Snake.class); Snake snake = mock(Snake.class);
doThrow(new IOException()).when(snake).sendMessage(anyString()); doThrow(new IOException()).when(snake).sendMessage(anyString());
SnakeTimer.addSnake(snake); SnakeTimer.addSnake(snake);
SnakeTimer.broadcast(""); SnakeTimer.broadcast("");
assertThat(SnakeTimer.getSnakes().size(), is(0)); assertThat(SnakeTimer.getSnakes().size(), is(0));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment