Corona Chat Walkthrough
In this wiki, we will walk through the integration of AppWarp Lua SDK with a simple Corona chat application.
Project Setup and Running
- Follow these steps and get your key pair and a room id.
- Download the chat sample code from our git repo.
- Copy the AppWarp folder from the latest version and put it in the Sample’s folder. It should look like this
- Edit main.lua and replace the keys and roomid where indicated with the values you got from AppHq dashboard
- Load the Sample in Corona Simulator and verify that it loads without any errors
Code Highlights We use Corona storyboard to design the application in two scenes. The first scene connects to appwarp cloud and joins the chat room. The seconds scene has the chat UI for sending some fixed messages (no keyboard) and viewing the last message received. The UI is basic but illustrates how to use the AppWarp apis to build a simple chat application.
main.lua
appWarpClient = require "AppWarp.WarpClient" appWarpClient.initialize(API_KEY, SECRET_KEY)
We create a global instance of the appwarp client and initialize it. It is important to keep this instance global and access the same one in your interactions with appwarp. Initialization with your developer keys is important so that your communication with the server is authenticated. Hence it must be called first up and before you connect with the server.
This following snippet is important as it provides for the asynchronous communication with the server. It registers the “enterFrame” listener with the gameLoop callback. In this callback we call the Loop api of the appwarp client instance. This allows appwarp client to check if there are any pending messages from the server and if so notify the application.
local function gameLoop(event) appWarpClient.Loop() end Runtime:addEventListener("enterFrame", gameLoop)
storyboard.gotoScene( "ConnectScene", "fade", 400 )
This takes us to the first scene of the application now that are initialization and set up is complete.
ConnectScene.lua
We add a text field to show the status of the application. Initialize it to indicate that the client is not connected.
statusText = display.newText( "Click to Connect to Start", 0, 0, native.systemFontBold, 24 )
We add a button to connect with the server. Concurrent connections to the same application in appwarp must have unique names. App developers are free to use any ID provider as long as it provides unique names such as facebook, google+ etc. or from their own user management system. In this case we simply use the time to get unique names.
connectButton = require("widget").newButton { left = (display.contentWidth-200)/2, top = display.contentHeight - 70, label = "Connect", width = 200, height = 40, cornerRadius = 4, onEvent = function(event) if "ended" == event.phase then statusText.text = "Connecting.." appWarpClient.connectWithUserName(tostring(os.clock())) -- join with a random name end end }
In order to receive callbacks, we need to register request listeners with the appwarp client instance. We do this in the enterScene event. We register listeners for the calls that we are going to make in this scene. Upon successful connection with the server, we will join and subscribe the chat room.
-- Called immediately after scene has moved onscreen: function scene:enterScene( event ) print( "1: enterScene event" ) statusText.text = "Click to Connect to Start" connectButton.isVisible = true appWarpClient.addRequestListener("onConnectDone", scene.onConnectDone) appWarpClient.addRequestListener("onJoinRoomDone", scene.onJoinRoomDone) appWarpClient.addRequestListener("onSubscribeRoomDone", scene.onSubscribeRoomDone) end function scene.onConnectDone(resultCode) if(resultCode == WarpResponseResultCode.SUCCESS) then statusText.text = "Joining room.." appWarpClient.joinRoom(STATIC_ROOM_ID) else statusText.text = "Connect failed.." end end function scene.onJoinRoomDone(resultCode) if(resultCode == WarpResponseResultCode.SUCCESS) then appWarpClient.subscribeRoom(STATIC_ROOM_ID) else statusText.text = "joinRoomDone failed" end end function scene.onSubscribeRoomDone(resultCode) if(resultCode == WarpResponseResultCode.SUCCESS) then storyboard.gotoScene( "ChatScene", "slideLeft", 800) else statusText.text = "subscribeRoom failed" end end
Subscribing the room is important as it allows the client to receive notifications from the room such as users joining/leaving the room and chat messages. Once done, we move to the next scene i.e. the “ChatScene”. We also hide the connect button so that its not visible in the chat scene.
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
connectButton.isVisible = false
end
ChatScene.lua
In this scene we allow the user to send messages and show the last received message. We define some fixed messages which we will send. Developers can integrate native keyboards as well however that is not the goal of this sample so we will simply exchange some hard coded messages to illustrate appwarp client integration.
This sends the message “Hello” to the room and it will be delivered by the server to all other subscribed users in that room.
helloButton = require("widget").newButton { left = (display.contentWidth-200)/2, top = display.contentHeight - 70, label = "Say Hello", width = 200, height = 40, cornerRadius = 4, onEvent = function(event) if "ended" == event.phase then appWarpClient.sendChat("Hello") end end }
When a chat message is received, we show it by updating the status text with it. You also need to register the chat notification listener with appwarp.
appWarpClient.addNotificationListener("onChatReceived", scene.onChatReceived)
Here is how you define the callback.
function scene.onChatReceived(sender, message) statusText.text = "new message: "..message end
This callback contains both the sender of the message and the message itself. To disconnect from the server, developers call the disconnect API and register for its callback. If the user disconnects or the client’s connection breaks due to external reasons, we navigate back to the connect scene.
function scene.onDisconnectDone(resultCode) if(resultCode ~= WarpResponseResultCode.SUCCESS) then statusText.text = "Disconnect failed.." else statusText.text = "Disconnected" storyboard.gotoScene( "ConnectScene", "slideLeft", 800 ) end end function scene.onConnectDone(resultCode) if(resultCode ~= WarpResponseResultCode.SUCCESS) then statusText.text = "Connect failed.." storyboard.gotoScene( "ConnectScene", "slideLeft", 800 ) end end
Upon leaving this scene we hide the buttons made visible for this scene
-- Called when scene is about to move offscreen: function scene:exitScene( event ) helloButton.isVisible = false byeButton.isVisible = false greetButton.isVisible = false disconnectButton.isVisible = false end