Touch enabled Pong implementation using SignalR

JavaScript

I’m not a JavaScript expert, actually I’m a total newbie. I’m following the discussion about JavaScript on the web now for a while, but my daily work involves more backend related technologies in a .Net framework environment. But, following a quite pragmatic approach, I enjoy playing a around with different stuff. Although, I do understand that JavaScript gets more and more important, especially if you think about mobile devices, I found it hard to get used to JavaScript. Maybe it’s because of my strong typed background I have, but the freedom you have in JavaScript drives me mad sometimes. So, please be patient with me and especially my JavaScript.

SignalR

I read about SignalR a few months ago and found it interesting right away. SignalR is a Client/Server long-polling framework, written by David Fowler and Damian Edwards, with jQuery part for the client and ASP.NET on the server. You can get SignalR from GitHub. For those of you who like to know more about SignalR, I recommend to listen to the hanselmitues episode. I personally used nuget, the new VS built-in packet manager,  to download and install the client and server components, that are mainly an assembly on the server and a few JS files on the client.

On the server you can inherit from PersistentConnection or Hub (I used the PersistentConnection, because it allows you use static data, like a list of Games for example). The hub has other advantages though, you could register typed callback functions on the client that are called on specific events on the server.

Pong

When I first heard about SignalR I thought about a way to demo it to my co-workers. My first approach was a website the had worm-hole on it. If you dragged a box on the website over a hole the box would disappear if you release the mouse and finally reappear on  a second website. All I had to do was to register two clients on the server and send the spawn info to the second client using the server in the middle. That was simple, but had quite an effect. It looked a bit like magic.

Then I thought, why not try to implement Pong. The playfield would be split over two clients. One player could steer the left, the other the right paddle. Finally, it must be fun if those paddles were touch enabled, that the game can played on two mobile devices.

Solution

I started with an empty ASP.NET project. After I added the SignalR references and the jquery.touch library (what you can find here).

image

Server

My SignalR server implementation has one main class, which is called server.vb (which will be shown later). The other classes are actually just types to help dealing with the JSON requests or responses. The server class holds a static type Games. Games is a collection of Game. Each Game holds exact two Player types.

First of all it’s important to add a route to the Global.asax, to enabled the SignalR server handler.

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        RouteTable.Routes.MapConnection(Of Server)("echo", "echo/{*operation}")
        TransportHeartBeat.Instance.DisconnectTimeout = TimeSpan.FromSeconds(15)
        TransportHeartBeat.Instance.HeartBeatInterval = TimeSpan.FromSeconds(15)
    End Sub

To ensure that the server recognizes if a connection is closed by the client and that the OnDisconnect event is fired, it is important to add the second two lines. Those lines configure the timeout when the server component should check if the client is still available.

The server class inherits from SignalR.PersistentConnection. I implemented to methods: OnRecievedAsync, OnDisconnect. The OnRecievedAsyny method is taking all requests from the clients. I created a simple protocol for my game. A client can send:

  • Hello, to register itself as a new player
  • spawn, to tell the server that the ball is now on the court of the other player
  • score, to tell the server that the other player made a goal
       Protected Overrides Function OnReceivedAsync(clientId As String, data As String) As Task
            Dim gr As New GameResponse With {.action = "unknown"}
            If data.StartsWith("hello") Then
                Dim pos As SpawnRequest.PaddlePosition = MyGames.AddPlayer(clientId)
                If Not MyGames.PlayersAreReady(clientId) Then
                    gr = New GameResponse With {.cmd = "init", .action = "wait", .clientId = clientId, .position = pos}
                Else
                    gr = New GameResponse With {.cmd = "init", .action = "go", .clientId = clientId, .position = pos}
                End If
            ElseIf data.StartsWith("spawn") Then
                Dim sr As New SpawnRequest(data)
                Dim p As Player = MyGames.GetOpponentPlayer(sr.ClientId)
                If Not p Is Nothing Then
                    gr = New GameResponse With {.cmd = "respawn",
                                               .clientId = p.ClientId,
                                               .position = p.Position,
                                               .X = sr.X,
                                               .Y = sr.Y,
                                               .VX = sr.Vx,
                                               .VY = sr.Vy}
                End If
            ElseIf data.StartsWith("score") Then
                Dim sc As New ScoreRequest(data)
                Dim p As Player = MyGames.GetOpponentPlayer(sc.ClientId)
                p.Score += 1
                If Not p Is Nothing Then
                    gr = New GameResponse With {.cmd = "newscore", .score = p.Score, .position = p.Position}
                End If
            End If
            If Not gr Is Nothing Then
                Return Connection.Broadcast(gr.ToJSON)
            End If
            Return Nothing
        End Function

     

    This is the complete communication between the server and the client. The requests and the responses are wrapped in JSON objects, actually to avoid string parsing on the client.

Client

On the client, you first want to initialize the connection to the server by passing the URL to the handler. Next you need to subscribe to the received event by provide a callback function.

connection = $.connection('echo');
connection.received(function(data) {
 var command = $.parseJSON(data.toString());
 if (command != null) {
       //analyze the command from the server ...     }
}

Finally we start the connection by calling the connection.start method and sending our first “hello” to the server if the connection could be established, by using another callback.

// Send a hello to the server
connection.start("", function () {
      connection.send("hello");
});

The rest of the code is just game stuff, which mainly contains of a loop that renders the ball, registers the touch ability for the paddle and that’s it.

Solution on github

I upload the project to github, you will find it here.

I hope you have fun with SignalR. I love it Open-mouthed smile

Advertisements

Fun with Lego

The QR barcode (Quick Response or just QR code) is a two-dimensional barcode that has become quite popular on mobile devices because the code typically contain URL that redirects you to a company’s website. There is no need to type the actual URL anymore.

While playing around with QR barcodes containing business card information my colleague Luzie came up with a very funny idea. She created a QR code  using Lego pieces.

IMG_2195-1

Scanning the code was more easy than I expected to be honest. The iPhone app (Optiscan) I used to scan the code easily picked up the information. Which appeared to be just a simple Hello World in the end Winking smile

Foto

By the way, you can do quite interesting things using QR codes. By benefitting from the very good failure tolerance of QR codes you can even place your logo in the middle of the code it self while the code information keeps readable. Like in this one that contains the DirectSmile Logo and a link to … well, what do you think?

DSMQR copy

Links to QR codes:
http://www.denso-wave.com/qrcode/qrfeature-e.html
http://en.wikipedia.org/wiki/QR_code

Have fun with QR codes,
Oliver