Spring Room!
We have a new sample room written in Java with the Spring framework:
This post is a brief overview of the creation process.
Jumpstart with code gen
Using this guide, we made a Spring microservice starter that could be deployed to Bluemix with just a few commands:
{% highlight shell_session %} $ bx dev create ? Select a pattern:
- Web App
- Mobile App
- Backend for Frontend
- Microservice
- MFP Enter a number> 4
? Select a starter:
- Basic Enter a number> 1
? Select a language:
- Java - MicroProfile / Java EE
- Node
- Python
- Java - Spring Framework Enter a number> 4
? Enter a name for your project> springmsdemo
? Enter a hostname for your project> springmsdemo
? Do you want to add services to your project? [y/n]> y
? Select a service:
- Cloudant NoSQL Database
- Object Storage Enter a number> 1
? Select a service plan:
- Lite
- Standard
- Dedicated Hardware Enter a number> 1
Successfully added service to project.
? Do you want to add another service? [y/n]> n
The project, springmsdemo, has been successfully saved into the current directory. OK {% endhighlight %}
Time to fill in our own code!
Borrowing from the Java room
The Java room had a lot of code we could reuse, so that's what we did.
Notable differences:
- We needed a WebSocketConfig to map our SocketHandler to
/room
WebSocketConfig to map our SocketHandler to/room
{% highlight java linenos %} @Configuration @EnableWebSocket class WebSocketConfig implements WebSocketConfigurer {
@Inject
SocketHandler handler;
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(handler, "/room");
}
} {% endhighlight %}
- We also needed to use a Spring WebSocket (
org.springframework.web.socket.WebSocketSession
) instead of the standard one (javax.websocket.Session
). It looks roughly like this (simplified): (org.springframework.web.socket.WebSocketSession
) instead of the standard one (javax.websocket.Session
). It looks roughly like this (simplified):
{% highlight java linenos %} @Component public class SocketHandler extends TextWebSocketHandler {
private final HashMap<String, WebSocketSession> sessions = new HashMap<>();
@Inject
private RoomImplementation roomImplementation;
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
session.sendMessage(new TextMessage(Message.ACK_MSG.toString()));
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session.getId());
Log.log(Level.INFO, this, "WebSocketSession with Id (" + session.getId() + ") closed with reason: " + status.getReason());
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
roomImplementation.handleMessage(new Message(message.getPayload().toString()), this);
}
public void sendMessage(Message message) {
for (WebSocketSession s : sessions.values()) {
sendMessageToSession(s, message);
}
}
private boolean sendMessageToSession(WebSocketSession session, Message message) {
try {
session.sendMessage(new TextMessage(message.toString()));
return true;
} catch (IOException e) {
...
}
}
...
} {% endhighlight %}
After porting some common code, we can run mvn spring-boot:run
to see our Spring room running locally!
Deploying to Bluemix
After adding Travis, Docker, and JaCoCo, we were ready to deploy to Bluemix:
bx dev build
then
bx dev deploy
and our room is deployed as a Cloud Foundry service with a reachable endpoint!
Registering the room with Game On!
Done!
/teleport spring-sample