Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
1a9ce42d
Commit
1a9ce42d
authored
Oct 09, 2013
by
Phillip Webb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply source formatting to samples
parent
efe102bd
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
428 additions
and
368 deletions
+428
-368
pom.xml
spring-boot-samples/pom.xml
+20
-0
pom.xml
spring-boot-samples/spring-boot-sample-websocket/pom.xml
+1
-0
GreetingService.java
...mework/boot/samples/websocket/client/GreetingService.java
+1
-0
SimpleClientWebSocketHandler.java
...amples/websocket/client/SimpleClientWebSocketHandler.java
+7
-4
SimpleGreetingService.java
.../boot/samples/websocket/client/SimpleGreetingService.java
+1
-0
DefaultEchoService.java
...ework/boot/samples/websocket/echo/DefaultEchoService.java
+1
-0
EchoService.java
...ingframework/boot/samples/websocket/echo/EchoService.java
+1
-0
EchoWebSocketHandler.java
...ork/boot/samples/websocket/echo/EchoWebSocketHandler.java
+20
-2
Direction.java
...ringframework/boot/samples/websocket/snake/Direction.java
+2
-1
Location.java
...pringframework/boot/samples/websocket/snake/Location.java
+42
-40
Snake.java
...g/springframework/boot/samples/websocket/snake/Snake.java
+111
-111
SnakeTimer.java
...ingframework/boot/samples/websocket/snake/SnakeTimer.java
+74
-80
SnakeUtils.java
...ingframework/boot/samples/websocket/snake/SnakeUtils.java
+29
-31
SnakeWebSocketHandler.java
...k/boot/samples/websocket/snake/SnakeWebSocketHandler.java
+80
-80
SampleWebSocketsApplicationTests.java
...ples/websocket/echo/SampleWebSocketsApplicationTests.java
+12
-9
SnakeTimerTests.java
...amework/boot/samples/websocket/snake/SnakeTimerTests.java
+26
-10
No files found.
spring-boot-samples/pom.xml
View file @
1a9ce42d
...
@@ -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>
...
...
spring-boot-samples/spring-boot-sample-websocket/pom.xml
View file @
1a9ce42d
...
@@ -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>
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/client/GreetingService.java
View file @
1a9ce42d
...
@@ -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
{
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/client/SimpleClientWebSocketHandler.java
View file @
1a9ce42d
...
@@ -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
();
}
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/client/SimpleGreetingService.java
View file @
1a9ce42d
...
@@ -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
{
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/echo/DefaultEchoService.java
View file @
1a9ce42d
...
@@ -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
{
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/echo/EchoService.java
View file @
1a9ce42d
...
@@ -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
{
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/echo/EchoWebSocketHandler.java
View file @
1a9ce42d
/*
* 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
);
}
}
...
...
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/Direction.java
View file @
1a9ce42d
...
@@ -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
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/Location.java
View file @
1a9ce42d
...
@@ -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
;
}
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/Snake.java
View file @
1a9ce42d
...
@@ -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
;
}
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/SnakeTimer.java
View file @
1a9ce42d
...
@@ -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
();
}
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/SnakeUtils.java
View file @
1a9ce42d
...
@@ -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
)
/
10000
f
;
float
saturation
=
(
random
.
nextInt
(
2000
)
+
1000
)
/
10000
f
;
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
;
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/main/java/org/springframework/boot/samples/websocket/snake/SnakeWebSocketHandler.java
View file @
1a9ce42d
...
@@ -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
)
/
10000
f
;
float
saturation
=
(
random
.
nextInt
(
2000
)
+
1000
)
/
10000
f
;
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
)));
}
}
}
spring-boot-samples/spring-boot-sample-websocket/src/test/java/org/springframework/boot/samples/websocket/echo/SampleWebSocketsApplicationTests.java
View file @
1a9ce42d
...
@@ -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
...
...
spring-boot-samples/spring-boot-sample-websocket/src/test/java/org/springframework/boot/samples/websocket/snake/SnakeTimerTests.java
View file @
1a9ce42d
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
));
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment