After I lined out some basic ideas about the game I want to make, I finally had time to start some implementation.
What happened
Not much actually... and I'm already sitting 8h on this thing.
Well, Pusher is easy going, but AWS SAM & Lambda & API-Gateway aren't that simple.
Project Setup
First I created a repo on GitHub in which I'm gonna version my game.
I split it up in back-end, which is a AWS SAM application, and front-end which is, at the moment a pile of garbage.
You need a server to handle authentication for Pusher presence channels, and I need them to keep track of players and distribute events to all players in a game.
Back-End
Currently it consist of 3 Lambda functions. The JavaScript in the back-ed/functions
directory gets wired up via the template.yaml
. AWS SAM Local is used for deployment.
-
hello
gets called by CloudWatch every minute and publishes a test message to the only channel
This is how a Lambda Function looks with a 1 minute rate schedule event:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./functions/hello
Events:
ScheduleOneMinuteEvent:
Type: Schedule
Properties:
Schedule: rate(1 minute)
-
pusherAuth
gets called by the Pusher client to allow a client to joint a presence channel
This is how a Lambda Function looks with an API-Gateway POST event:
PusherAuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./functions/pusherAuth
Events:
pusherAuthEvent:
Type: Api
Properties:
Path: /pusherauth
Method: post
This is how my simple authentication code looks like at the moment:
// Loading and initializing Pusher server API
// only on a cold start
const Pusher = require("pusher");
const pusher = new Pusher({
appId: process.env.APP_ID,
key: process.env.APP_KEY,
secret: process.env.SECRET_KEY
});
exports.handler = (event, context, callback) => {
// the Pusher client doesn't send JSON, so I just crack it open manually
const body = event.body.split("&");
const socket_id = body[0].split("=")[1];
const channel_name = body[1].split("=")[1];
// some data Pusher will distribute to the clients on channel subscription
const presenceData = {
user_id: socket_id,
user_info: {
name: "Player " + Math.random()
}
};
// checking if this is all good and well, hurr
const auth = pusher.authenticate(socket_id, channel_name, presenceData);
// API-Gateway wants its response it that format
const response = {
statusCode: 200,
body: JSON.stringify(auth)
};
callback(null, response);
};
-
getGameChannel
gives the client a channel to join, later this gets more logic to check which games are open, not full, waiting for players etc.
Front-End
Not much happening here. Got a Bootstrap theme, loaded the Pusher client and connected.
The whole thing is hosted on Github Pages.
Problems
CORS setup seems to be a huge pain with AWS SAM, so I'm using CORS Everywhere until I get this fixed.
Packaging of Lambda functions is needed. Currently I have to copy the
node_modules
directory into every function directory before packaging. Would be cool if I could simply install it in theback-end
directory and it gets copied automatically.Some helper functions are needed too. The whole Lambda experience is very basic at the moment.