Implementing Chip-8

Posted By Hoyt Summers Pittman

It has been a hobby of mine to create a video game console, but we live in a world where anyone can buy a $35 Raspberry Pi and install every 8, 16, and 32 bit game on it. So I have focused more on how consoles and software work and are made than actually making one. As part of this I have actually implemented an emulator of sorts, “Chip-8”.

Chip 8 was not a game console, but instead it is a byte-code interpreter that was originally run on 8-bit computers in the 1970s. It is, however, a good beginners project. My implementation took about 2 weeks to program and test. I have had a lot of success with running roms I have found online, and I am documenting it to share as a learning project for people that want to learn more about emulation, low level programming, or just like programming.

Now, enjoy my demo :

Aug 5th, 2016

Undertow Websocket Client in Java SE

Posted By Hoyt Summers Pittman

Undertow is a web server written in Java by JBoss. It uses a very modular architecture which allows the developer to pick and choose features they need so it fits anywhere from a Java EE web-server (Wildfly) to being embedded in a JavaSE application (the topic of this blog). Actually, this post isn’t about a web server AT ALL! This post is about using Undertow’s web socket library in a Java FX application to allow a server to send real time messages.

I’ve been working on a side project to make managing my Github notifications easier. The general idea is that a server will record my notifications, apply basic filtering on them, and then show me notifications ranked “Low”, “Medium”, and “High” priority. The UI of this application will be provided by Java FX and run standalone on the user’s system. A brief demo can be found on YouTube.

I originally tried the WebSocket implementation by TooTallNate, but they wouldn’t work correctly in my situation. I settled on the Undertow implementation mostly because I work for RedHat and can harass the developers on internal channels; however, this wasn’t needed.

The Undertow page mostly deals with server to server communication and the only WebSocket client example I could find that spoke to my situation was in a single unit test. However, I was able to cargo cult most of a working project, but I need to learn more about Xnio.

WebSocketProvider

The first thing I had to do was configure a XnioWorker. This static block is mostly cargo culture so I would refer to the official Xnio site before putting this into production.

    private static XnioWorker worker;

    static {
        try {
            worker = Xnio.getInstance().createWorker(OptionMap.builder()
                    .set(Options.WORKER_IO_THREADS, 2)
                    .set(Options.CONNECTION_HIGH_WATER, 1000000)
                    .set(Options.CONNECTION_LOW_WATER, 1000000)
                    .set(Options.WORKER_TASK_CORE_THREADS, 30)
                    .set(Options.WORKER_TASK_MAX_THREADS, 30)
                    .set(Options.TCP_NODELAY, true)
                    .set(Options.CORK, true)
                    .getMap());
        } catch (IOException | IllegalArgumentException ex) {
            Logger.getLogger(WebsocketProvider.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }

Next, I created a static method to create a WebSocketClient instance and connect to my server. Because I am using self signed certificates as part of testing, I implemented a method to create an appropriate socket.

    public static WebSocketChannel getWebsocketClient(URI serverURI, String bearerToken, EventBus bus) {
        try {


            WebSocketClient.ConnectionBuilder builder = WebSocketClient.connectionBuilder(worker, new DefaultByteBufferPool(false, 2048), serverURI);
            builder.setClientNegotiation(new WebSocketClientNegotiation(null, null){
                @Override
                public void beforeRequest(Map<string , List<String>> headers) {
                    headers.put("Authorization", Lists.newArrayList("bearer " + bearerToken));
                }
            });

            if ("wss".equals(serverURI.getScheme())) {
                setupSSLSocket(builder);
            }

            WebSocketChannel channel = builder.connect().get();
            channel.resumeReceives();

            channel.getReceiveSetter().set(new AbstractReceiveListener() {
                @Override
                protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
                    bus.post(UPDATE_NOTIFICATIONS);

                }

                @Override
                protected void onText(WebSocketChannel webSocketChannel, StreamSourceFrameChannel messageChannel) throws IOException {
                    super.onText(webSocketChannel, messageChannel); //To change body of generated methods, choose Tools | Templates.
                    bus.post(UPDATE_NOTIFICATIONS);
                }

                @Override
                protected void onError(WebSocketChannel channel, Throwable error) {
                    super.onError(channel, error);
                    Logger.getLogger(WebsocketProvider.class.getName()).log(Level.SEVERE, error.getMessage(), error);

                }
            });

            return channel;
        } catch (IOException | CancellationException ex) {
            Logger.getLogger(WebsocketProvider.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }

    }

There are three pieces of code to pay special attention to channel.resumeReceives();, the WebSocketClientNegotiation implementation and the AbstractReceiveListener implementation. The first is necessary to receive messages from the server (I don’t know why, can someone from Undertow shed some light). The second adds a Bearer token authorization header so the server can authenticate the user with KeyCloak. The last is the actual handler for messages from the server. Currently it posts the message to an EventBus that various components are subscribed to.

There we have it! A very VERY simple websocket client for my Java FX application. If you want to play with it you can find the server and client source codes on my GitHub.

Jul 10th, 2016

Reporting Gradle Builds using WebSockets

Posted By Hoyt Summers Pittman

If you have a build server you might want to receive reporting from your build. Many build bots offer this kind of reporting, but I decided to implement it myself in a standard Gradle build script. I override the default logger and replace it with one that writes all of the logging to a web socket. I have also created a very simple Java EE service which can consume logging messages and rebroadcast them to a different web socket using JMS¹.

Gradle Configuration

buildscript {
    dependencies {
        /* I'm using the tyrus libraries for my web socket client.
         Because logging is part of the build and not the project, 
         they must be declared classpath and in the buildscript.dependencies
         stanza.    
        */
        classpath 'org.glassfish.tyrus:tyrus-client:1.+'
        classpath 'org.glassfish.tyrus:tyrus-server:1.+'
        classpath 'org.glassfish.tyrus:tyrus-container-grizzly:1.+'
    }
}
//Now we begin the setup for the WebSocket Logger
import org.glassfish.tyrus.client.*;

gradle.useLogger(new WebSocketLogger());

class WebSocketLogger implements org.gradle.api.logging.StandardOutputListener {

    def manager = ClientManager.createClient();
    def session = manager.connectToServer(WebSocketLoggerClientEndpoint.class, java.net.URI.create("ws://localhost:8080/log_viewer/logging"));

    // useLogger replaces the default logging.  I am writing to a tmp file for debugging purposes.
    def tmp = new File('/tmp/log.txt');

    @Override
    void onOutput(CharSequence charSequence) {
        tmp.append(charSequence +"\n");
        session.basicRemote.sendText(charSequence.toString());
    }

    @javax.websocket.ClientEndpoint
    class WebSocketLoggerClientEndpoint {

        @javax.websocket.OnMessage
        public void processMessageFromServer(String message, javax.websocket.Session session) {
            tmp.append(message +"\n");
        }

        @javax.websocket.OnError
        public void handleError(javax.websocket.Session session, Throwable thr) {
            tmp.append('Err' + thr.message +"\n");
        }
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

Java EE Server

The server side was more complex because of how CDI and WebSockets interact in Java EE 7. The code is really simple and benefits much more from browsing in GitHub than in snippets here. You may view the server source here : https://github.com/secondsun/log_viewer².

All this code does is take messages sent to the socket found at “ws://localhost:8080/log_viewer/logging” and rebroadcasts them to “ws://localhost:8080/log_viewer/read”

Conclusion

Being able to rebroadcast log messages is neat and useful. Additionally having a working example for connecting websockets to JMS was a lot of fun to put together.

Foot notes

1: I would have used CDI events, but CDI and the ServerEndpoint annotation do not get along. There are several JIRAs tracking this issue.
* WEBSOCKET_SPEC-196
* JMS_SPEC-121
* CDI-370
2: Thanks to https://blogs.oracle.com/brunoborges/entry/integrating_websockets_and_jms_with for help with getting this working.

May 25th, 2016

AeroGear Android 3.0

Posted By Hoyt Summers Pittman

So it has been a while, but AeroGear Android 3.0 is out. As fitting a major number release we have a few breaking changes, lots of bug fixes, and a few new features. The full changelist can be viewed on our JIRA page

Changes

Breaking Changes

New Features

  • aerogear-android-push now uses GCM 3 including GcmListener, InstanceID, and GCM Topics.
  • Android 23 support
  • Material design in cookbooks

Minor Changes

  • JUnit 4 based automated tests
  • Updates to all required libraries (Android SDK, Android Maven Plugin)

How to get it

In Android Studio just declare our dependencies in your build.gradle file. Feel free to mix and match as necessary.

    compile 'org.jboss.aerogear:aerogear-android-core:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-security:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-store:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-pipe:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-auth:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-authz:3.0.0'
    compile 'org.jboss.aerogear:aerogear-android-push:3.0.1'

Also, feel free to take our cookbook samples for a spin!

How to get involved

Feel free to join us at #aerogear on IRC, follow us @aerogears on Twitter, or also join our aerogear-dev and aerogear-users mailing lists. For more details please check out our Community Page.

May 17th, 2016
Next Page »