Skip to content

Instantly share code, notes, and snippets.

@crimsonred
Created Dec 9, 2014
Embed
What would you like to do?
Blog post to demonstrate GAE Example using PubNub's Go SDK for GAE

Using PubNub’s Go GAE SDK

This tutorial will show you how to create an GAE app using PubNub’s Go GAE SDK. We will create an app to demonstrate the features available on the PubNub’s Go SDK. The example will let you 'subscribe' to a PubNub channel, 'publish' and receive messages on it.

Prerequisites:

  • Install Eclipse IDE.

  • Download and install Google App Engine SDK for Go. (https://cloud.google.com/appengine/downloads)

  • Install golang plugin for Eclipse.

  • Clone https://github.com/pubnub/go.git, we will use the code from the directories 'gae-example' and 'gae'

  • The SDK has a dependency on Gorilla web toolkit for sessions (http://www.gorillatoolkit.org). You need to download Gorilla web toolkit from the git repo using go get github.com/gorilla/sessions and copy it to github.com/gorilla/sessions in your project maintaining the folder structure.

Code walkthrough:

Subscribe to PubNub channel using Javascript

The Subscribe/Presence/Unsubscribe are implemented on the 'client' end using PubNub’s Javascript SDK.

To use the SDK we need to include the JavaScript SDK in the code.

<script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>

Initialize with Publish & Subscribe Keys in Javascript. The uuid for the application is sent from the server.

pubnub = PUBNUB.init({

            publish_key   : $('#publishKey').val(),
            subscribe_key : $('#subscribeKey').val(),
            cipher_key : $('#cipher').val(),
            ssl : isSsl,
            uuid: '{{.uuid}}',
        });
  • 'Publish Key': Your Publish Key.

  • 'Subscribe Key': Your Subscribe Key.

  • 'Cipher': Cipher key for encryption, can be empty.

  • 'SSL': true or false, to enable or disable SSL.

  • 'UUID': can be empty or you can set a custom UUID.

Subscribe to a PubNub channel in Javascript.

We need to 'subscribe' to a channel to receive all the messages sent on the channel. This is done by using the following code.

//Init pubnub instance in javascript

var channel = 'testchannel';
pubnub.subscribe({
		channel : channel,
		message : function(m){ addMessage(JSON.stringify(m)); },
		connect : function(){ addMessage("connected"); },
	})
addMessage("Subscribing using JS SDK to channel: " + channel);

anchor:0[] Here 'channel' is the name of the PubNub channel which we are subscribing to. The 'subscribe' method asks for 2 callback methods, one for receiving the messages and the other to receive the connect status.

Publish a message using the PubNub’s GO GAE SDK

'Publish' runs on the app engine. A 'button' input type is created on the HTML page. This button is linked to a javascript function which asks the user to enter the message to 'publish'. When entered the query is posted using jQuery to the server. This calls the 'publish' handler on the server.

The following code is used on the server to create the Publish feature:

Import the dependency

import (
	"github.com/pubnub/go/gae/messaging"
)
  • 'github.com/pubnub/go/gae/messaging' is the reference to PubNub’s GAE SDK using GO.

Initialize a new Pubnub instance

anchor:1[] To use the PubNub SDK we need to instantiate its instance. The instantiation is done my calling the 'new' method of the messaging package.

pubInstance := messaging.New(<AppEngine context>, <UUID>, <http.ResponseWriter>, <*http.Request>, <YOUR PUBLISH KEY>, <YOUR SUBSCRIBE KEY>, <SECRET KEY>, <CIPHER>, <SSL ON/OFF>, )

The 'New' constructor takes the following parameters:

  • 'AppEngine context': reference of the context from the app engine.

  • 'UUID': can be empty or you can set a custom UUID.

  • 'http.ResponseWriter': reference of the ResponseWriter from the mux.

  • 'Publish Key': Your Publish Key.

  • 'Subscribe Key': Your Subscribe Key.

  • 'Secret Key': Your Secret Key.

  • 'Cipher': Cipher key for encryption, can be empty.

  • 'SSL': true or false, to enable or disable SSL.

Publish

//Init pubnub instance

var errorChannel = make(chan []byte)
var callbackChannel = make(chan []byte)
go pubInstance.Publish(<AppEngine context>, <http.ResponseWriter>, <*http.Request>, <pubnub channel>, <message to publish>, callbackChannel, errorChannel)

handleResult(<AppEngine context>, <http.ResponseWriter>, <*http.Request>, <UUID>, callbackChannel, errorChannel, messaging.GetNonSubscribeTimeout(), "Publish")

Please see this for [1] for an implementation of 'Init' and this [2] for 'handleResult'.

In the 'Publish' method you need to give same PubNub channel name as the one subscribed (using Javascript). And the message to 'publish'.

The 'callbackChannel' is called when we the message is successfully posted. The response is something like this:

[1,"Sent","14180623236103293"]

The 'errorChannel' is called when there is an error publishing the message. Like incase of a timeout when publishing the message.

anchor:2[] handleResult

This function is a utility function used in the examples below to handle the non Subscribe/Presence response. You would want to adapt it to your own needs. This function reads both the 'errorChannel' and 'callbackChannel' until we get a response on either of the go channels.

func handleResult(c appengine.Context, w http.ResponseWriter, r *http.Request, uuid string, successChannel, errorChannel chan []byte, timeoutVal uint16, action string) {
	//c := appengine.NewContext(r)
	for {
		select {

		case success, ok := <-successChannel:
			if !ok {
				c.Infof("success!OK")
				break
			}
			if string(success) != "[]" {
				c.Infof("success:", string(success))
				sendResponseToChannel(w, string(success), r, uuid)
			}

			return
		case failure, ok := <-errorChannel:
			if !ok {
				c.Infof("fail1:", string("failure"))
				break
			}
			if string(failure) != "[]" {
				c.Infof("fail:", string(failure))
				sendResponseToChannel(w, string(failure), r, uuid)
			}
			return
		}
	}
}

When the message is 'published' the same message will be displayed in the text area on the browser as we are 'subscribed' to the channel.

How to run

Configuration:

  • Run the following command on the terminal/command prompt.

go get github.com/pubnub/go/messaging

This command imports the PubNub’s Go SDK to the path '<Go-Workspace-Folder>/src/pubnub/go'

Run the example:

  • Run the PubNub GAE example using GO on the dev app server using the command <PATH-to-go_appengine/dev_appserver.py> <Path-to-PubNub-GAE-Folder> --port <port-number-of-your-choice>

  • Run http://localhost:<port-number-of-provided-in-the-command-above>;

  • On run click the 'Connect' button to connect to the server.

  • To 'subscribe' to a channel click the button 'Subscribe using JS SDK'. This will ask for a channel name, on providing a channel name the application will 'subscribe' to the channel.

  • 'Publish' a message by clicking the 'publish' button. It will ask for a channel name and the message to publish. On providing both the values the message will be published on the channel.

  • The callback message from the 'Publish' call will be displayed in the message area on the browser.

  • And so will the message that is received in the 'Subscribe' callback.

The complete code is available here:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.9" />
<title>Using PubNub&#8217;s Go GAE SDK</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
/* Default font. */
body {
font-family: Georgia,serif;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Arial,Helvetica,sans-serif;
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
h5 {
font-size: 1.0em;
}
div.sectionbody {
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
ul > li { color: #aaa; }
ul > li > * { color: black; }
.monospaced, code, pre {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
padding: 0;
margin: 0;
}
pre {
white-space: pre-wrap;
}
#author {
color: #527bbd;
font-weight: bold;
font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}
#footer {
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
#footer-text {
float: left;
padding-bottom: 0.5em;
}
#footer-badges {
float: right;
padding-bottom: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.0em;
margin-bottom: 2.0em;
margin-right: 10%;
color: #606060;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid #dddddd;
border-left: 4px solid #f0f0f0;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid #dddddd;
border-left: 5px solid #f0f0f0;
background: #f8f8f8;
padding: 0.5em;
}
div.quoteblock, div.verseblock {
padding-left: 1.0em;
margin-left: 1.0em;
margin-right: 10%;
border-left: 5px solid #f0f0f0;
color: #888;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock > pre.content {
font-family: inherit;
font-size: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 3px solid #dddddd;
}
div.exampleblock > div.content {
border-left: 3px solid #dddddd;
padding-left: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
.footnote, .footnoteref {
font-size: 0.8em;
}
span.footnote, span.footnoteref {
vertical-align: super;
}
#footnotes {
margin: 20px 0 20px 0;
padding: 7px 0 0 0;
}
#footnotes div.footnote {
margin: 0 0 5px 0;
}
#footnotes hr {
border: none;
border-top: 1px solid silver;
height: 1px;
text-align: left;
margin-left: 0;
width: 20%;
min-width: 100px;
}
div.colist td {
padding-right: 0.5em;
padding-bottom: 0.3em;
vertical-align: top;
}
div.colist td img {
margin-top: 0.3em;
}
@media print {
#footer-badges { display: none; }
}
#toc {
margin-bottom: 2.5em;
}
#toctitle {
color: #527bbd;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }
span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }
span.big { font-size: 2em; }
span.small { font-size: 0.6em; }
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
div.unbreakable { page-break-inside: avoid; }
/*
* xhtml11 specific
*
* */
div.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead, p.table.header {
font-weight: bold;
color: #527bbd;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
/*
* html5 specific
*
* */
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #527bbd;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #527bbd;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #527bbd;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
/*
* manpage specific
*
* */
body.manpage h1 {
padding-top: 0.5em;
padding-bottom: 0.5em;
border-top: 2px solid silver;
border-bottom: 2px solid silver;
}
body.manpage h2 {
border-style: none;
}
body.manpage div.sectionbody {
margin-left: 3em;
}
@media print {
body.manpage div#toc { display: none; }
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = { // Namespace.
/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////
/* Author: Mihai Bazon, September 2002
* http://students.infoiasi.ro/~mishoo
*
* Table Of Content generator
* Version: 0.4
*
* Feel free to use this script under the terms of the GNU General Public
* License, as long as you do not remove or alter this notice.
*/
/* modified by Troy D. Hanson, September 2006. License: GPL */
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
// toclevels = 1..4.
toc: function (toclevels) {
function getText(el) {
var text = "";
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
text += i.data;
else if (i.firstChild != null)
text += getText(i);
}
return text;
}
function TocEntry(el, text, toclevel) {
this.element = el;
this.text = text;
this.toclevel = toclevel;
}
function tocEntries(el, toclevels) {
var result = new Array;
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
// Function that scans the DOM tree for header elements (the DOM2
// nodeIterator API would be a better technique but not supported by all
// browsers).
var iterate = function (el) {
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
var mo = re.exec(i.tagName);
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
}
iterate(i);
}
}
}
iterate(el);
return result;
}
var toc = document.getElementById("toc");
if (!toc) {
return;
}
// Delete existing TOC entries in case we're reloading the TOC.
var tocEntriesToRemove = [];
var i;
for (i = 0; i < toc.childNodes.length; i++) {
var entry = toc.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div'
&& entry.getAttribute("class")
&& entry.getAttribute("class").match(/^toclevel/))
tocEntriesToRemove.push(entry);
}
for (i = 0; i < tocEntriesToRemove.length; i++) {
toc.removeChild(tocEntriesToRemove[i]);
}
// Rebuild TOC entries.
var entries = tocEntries(document.getElementById("content"), toclevels);
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.element.id == "")
entry.element.id = "_toc_" + i;
var a = document.createElement("a");
a.href = "#" + entry.element.id;
a.appendChild(document.createTextNode(entry.text));
var div = document.createElement("div");
div.appendChild(a);
div.className = "toclevel" + entry.toclevel;
toc.appendChild(div);
}
if (entries.length == 0)
toc.parentNode.removeChild(toc);
},
/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////
/* Based on footnote generation code from:
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
*/
footnotes: function () {
// Delete existing footnote entries in case we're reloading the footnodes.
var i;
var noteholder = document.getElementById("footnotes");
if (!noteholder) {
return;
}
var entriesToRemove = [];
for (i = 0; i < noteholder.childNodes.length; i++) {
var entry = noteholder.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
entriesToRemove.push(entry);
}
for (i = 0; i < entriesToRemove.length; i++) {
noteholder.removeChild(entriesToRemove[i]);
}
// Rebuild footnote entries.
var cont = document.getElementById("content");
var spans = cont.getElementsByTagName("span");
var refs = {};
var n = 0;
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnote") {
n++;
var note = spans[i].getAttribute("data-note");
if (!note) {
// Use [\s\S] in place of . so multi-line matches work.
// Because JavaScript has no s (dotall) regex flag.
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
spans[i].innerHTML =
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
spans[i].setAttribute("data-note", note);
}
noteholder.innerHTML +=
"<div class='footnote' id='_footnote_" + n + "'>" +
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
n + "</a>. " + note + "</div>";
var id =spans[i].getAttribute("id");
if (id != null) refs["#"+id] = n;
}
}
if (n == 0)
noteholder.parentNode.removeChild(noteholder);
else {
// Process footnoterefs.
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnoteref") {
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
href = href.match(/#.*/)[0]; // Because IE return full URL.
n = refs[href];
spans[i].innerHTML =
"[<a href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
}
}
}
},
install: function(toclevels) {
var timerId;
function reinstall() {
asciidoc.footnotes();
if (toclevels) {
asciidoc.toc(toclevels);
}
}
function reinstallAndRemoveTimer() {
clearInterval(timerId);
reinstall();
}
timerId = setInterval(reinstall, 500);
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
else
window.onload = reinstallAndRemoveTimer;
}
}
asciidoc.install();
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Using PubNub&#8217;s Go GAE SDK</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>This tutorial will show you how to create an GAE app using PubNub&#8217;s Go GAE SDK. We will create an app to demonstrate the features available on the PubNub&#8217;s Go SDK. The example will let you <em>subscribe</em> to a PubNub channel, <em>publish</em> and receive messages on it.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_prerequisites">Prerequisites:</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Install Eclipse IDE.
</p>
</li>
<li>
<p>
Download and install Google App Engine SDK for Go. (<a href="https://cloud.google.com/appengine/downloads">https://cloud.google.com/appengine/downloads</a>)
</p>
</li>
<li>
<p>
Install golang plugin for Eclipse.
</p>
</li>
<li>
<p>
Clone <a href="https://github.com/pubnub/go.git">https://github.com/pubnub/go.git</a>, we will use the code from the directories <em>gae-example</em> and <em>gae</em>
</p>
</li>
<li>
<p>
The SDK has a dependency on Gorilla web toolkit for sessions (<a href="http://www.gorillatoolkit.org">http://www.gorillatoolkit.org</a>). You need to download Gorilla web toolkit from the git repo using go get github.com/gorilla/sessions and copy it to github.com/gorilla/sessions in your project maintaining the folder structure.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_code_walkthrough">Code walkthrough:</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_subscribe_to_pubnub_channel_using_javascript">Subscribe to PubNub channel using Javascript</h3>
<div class="paragraph"><p>The Subscribe/Presence/Unsubscribe are implemented on the <em>client</em> end using PubNub&#8217;s Javascript SDK.</p></div>
<div class="paragraph"><p>To use the SDK we need to include the JavaScript SDK in the code.</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-weight: bold"><span style="color: #0000FF">&lt;script</span></span> <span style="color: #009900">src</span><span style="color: #990000">=</span><span style="color: #FF0000">"http://cdn.pubnub.com/pubnub-3.7.1.min.js"</span><span style="font-weight: bold"><span style="color: #0000FF">&gt;&lt;/script&gt;</span></span></tt></pre></div></div>
<div class="sect3">
<h4 id="_initialize_with_publish_amp_subscribe_keys_in_javascript_the_uuid_for_the_application_is_sent_from_the_server">Initialize with Publish &amp; Subscribe Keys in Javascript. The uuid for the application is sent from the server.</h4>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> pubnub <span style="color: #990000">=</span> PUBNUB<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">init</span></span><span style="color: #990000">(</span><span style="color: #FF0000">{</span>
<span style="color: #000000"> 2:</span>
<span style="color: #000000"> 3:</span> publish_key <span style="color: #990000">:</span> $<span style="color: #990000">(</span><span style="color: #FF0000">'#publishKey'</span><span style="color: #990000">).</span><span style="font-weight: bold"><span style="color: #000000">val</span></span><span style="color: #990000">(),</span>
<span style="color: #000000"> 4:</span> subscribe_key <span style="color: #990000">:</span> $<span style="color: #990000">(</span><span style="color: #FF0000">'#subscribeKey'</span><span style="color: #990000">).</span><span style="font-weight: bold"><span style="color: #000000">val</span></span><span style="color: #990000">(),</span>
<span style="color: #000000"> 5:</span> cipher_key <span style="color: #990000">:</span> $<span style="color: #990000">(</span><span style="color: #FF0000">'#cipher'</span><span style="color: #990000">).</span><span style="font-weight: bold"><span style="color: #000000">val</span></span><span style="color: #990000">(),</span>
<span style="color: #000000"> 6:</span> ssl <span style="color: #990000">:</span> isSsl<span style="color: #990000">,</span>
<span style="color: #000000"> 7:</span> uuid<span style="color: #990000">:</span> <span style="color: #FF0000">'{{.uuid}}'</span><span style="color: #990000">,</span>
<span style="color: #000000"> 8:</span> <span style="color: #FF0000">}</span><span style="color: #990000">);</span></tt></pre></div></div>
<div class="ulist"><ul>
<li>
<p>
<em>Publish Key</em>: Your Publish Key.
</p>
</li>
<li>
<p>
<em>Subscribe Key</em>: Your Subscribe Key.
</p>
</li>
<li>
<p>
<em>Cipher</em>: Cipher key for encryption, can be empty.
</p>
</li>
<li>
<p>
<em>SSL</em>: true or false, to enable or disable SSL.
</p>
</li>
<li>
<p>
<em>UUID</em>: can be empty or you can set a custom UUID.
</p>
</li>
</ul></div>
</div>
<div class="sect3">
<h4 id="_subscribe_to_a_pubnub_channel_in_javascript">Subscribe to a PubNub channel in Javascript.</h4>
<div class="paragraph"><p>We need to <em>subscribe</em> to a channel to receive all the messages sent on the channel. This is done by using the following code.</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-style: italic"><span style="color: #9A1900">//Init pubnub instance in javascript</span></span>
<span style="color: #000000"> 2:</span>
<span style="color: #000000"> 3:</span> <span style="font-weight: bold"><span style="color: #0000FF">var</span></span> channel <span style="color: #990000">=</span> <span style="color: #FF0000">'testchannel'</span><span style="color: #990000">;</span>
<span style="color: #000000"> 4:</span> pubnub<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">subscribe</span></span><span style="color: #990000">(</span><span style="color: #FF0000">{</span>
<span style="color: #000000"> 5:</span> channel <span style="color: #990000">:</span> channel<span style="color: #990000">,</span>
<span style="color: #000000"> 6:</span> message <span style="color: #990000">:</span> <span style="font-weight: bold"><span style="color: #0000FF">function</span></span><span style="color: #990000">(</span>m<span style="color: #990000">)</span><span style="color: #FF0000">{</span> <span style="font-weight: bold"><span style="color: #000000">addMessage</span></span><span style="color: #990000">(</span>JSON<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">stringify</span></span><span style="color: #990000">(</span>m<span style="color: #990000">));</span> <span style="color: #FF0000">}</span><span style="color: #990000">,</span>
<span style="color: #000000"> 7:</span> connect <span style="color: #990000">:</span> <span style="font-weight: bold"><span style="color: #0000FF">function</span></span><span style="color: #990000">()</span><span style="color: #FF0000">{</span> <span style="font-weight: bold"><span style="color: #000000">addMessage</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"connected"</span><span style="color: #990000">);</span> <span style="color: #FF0000">}</span><span style="color: #990000">,</span>
<span style="color: #000000"> 8:</span> <span style="color: #FF0000">}</span><span style="color: #990000">)</span>
<span style="color: #000000"> 9:</span> <span style="font-weight: bold"><span style="color: #000000">addMessage</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"Subscribing using JS SDK to channel: "</span> <span style="color: #990000">+</span> channel<span style="color: #990000">);</span></tt></pre></div></div>
<div class="paragraph"><p><a id="0"></a> Here <em>channel</em> is the name of the PubNub channel which we are subscribing to. The <em>subscribe</em> method asks for 2 callback methods, one for receiving the messages and the other to receive the connect status.</p></div>
</div>
</div>
<div class="sect2">
<h3 id="_publish_a_message_using_the_pubnub_8217_s_go_gae_sdk">Publish a message using the PubNub&#8217;s GO GAE SDK</h3>
<div class="paragraph"><p><em>Publish</em> runs on the app engine. A <em>button</em> input type is created on the HTML page. This button is linked to a javascript function which asks the user to enter the message to <em>publish</em>. When entered the query is posted using jQuery to the server. This calls the <em>publish</em> handler on the server.</p></div>
<div class="paragraph"><p>The following code is used on the server to create the Publish feature:</p></div>
<div class="sect3">
<h4 id="_import_the_dependency">Import the dependency</h4>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-weight: bold"><span style="color: #0000FF">import</span></span> <span style="color: #990000">(</span>
<span style="color: #000000"> 2:</span> <span style="color: #FF0000">"github.com/pubnub/go/gae/messaging"</span>
<span style="color: #000000"> 3:</span> <span style="color: #990000">)</span></tt></pre></div></div>
<div class="ulist"><ul>
<li>
<p>
<em>github.com/pubnub/go/gae/messaging</em> is the reference to PubNub&#8217;s GAE SDK using GO.
</p>
</li>
</ul></div>
</div>
<div class="sect3">
<h4 id="_initialize_a_new_pubnub_instance">Initialize a new Pubnub instance</h4>
<div class="paragraph"><p><a id="1"></a> To use the PubNub SDK we need to instantiate its instance. The instantiation is done my calling the <em>new</em> method of the messaging package.</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>pubInstance <span style="color: #990000">:=</span> messaging<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">New</span></span><span style="color: #990000">(&lt;</span>AppEngine context<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>UUID<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>http<span style="color: #990000">.</span>ResponseWriter<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;*</span>http<span style="color: #990000">.</span>Request<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>YOUR PUBLISH KEY<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>YOUR SUBSCRIBE KEY<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>SECRET KEY<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>CIPHER<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>SSL ON<span style="color: #990000">/</span>OFF<span style="color: #990000">&gt;,</span> <span style="color: #990000">)</span></tt></pre></div></div>
<div class="paragraph"><p>The <em>New</em> constructor takes the following parameters:</p></div>
<div class="ulist"><ul>
<li>
<p>
<em>AppEngine context</em>: reference of the context from the app engine.
</p>
</li>
<li>
<p>
<em>UUID</em>: can be empty or you can set a custom UUID.
</p>
</li>
<li>
<p>
<em>http.ResponseWriter</em>: reference of the ResponseWriter from the mux.
</p>
</li>
<li>
<p>
<em>Publish Key</em>: Your Publish Key.
</p>
</li>
<li>
<p>
<em>Subscribe Key</em>: Your Subscribe Key.
</p>
</li>
<li>
<p>
<em>Secret Key</em>: Your Secret Key.
</p>
</li>
<li>
<p>
<em>Cipher</em>: Cipher key for encryption, can be empty.
</p>
</li>
<li>
<p>
<em>SSL</em>: true or false, to enable or disable SSL.
</p>
</li>
</ul></div>
</div>
<div class="sect3">
<h4 id="_publish">Publish</h4>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-style: italic"><span style="color: #9A1900">//Init pubnub instance</span></span>
<span style="color: #000000"> 2:</span>
<span style="color: #000000"> 3:</span> <span style="font-weight: bold"><span style="color: #0000FF">var</span></span> errorChannel <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">make</span></span><span style="color: #990000">(</span><span style="font-weight: bold"><span style="color: #0000FF">chan</span></span> <span style="color: #990000">[]</span><span style="color: #009900">byte</span><span style="color: #990000">)</span>
<span style="color: #000000"> 4:</span> <span style="font-weight: bold"><span style="color: #0000FF">var</span></span> callbackChannel <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">make</span></span><span style="color: #990000">(</span><span style="font-weight: bold"><span style="color: #0000FF">chan</span></span> <span style="color: #990000">[]</span><span style="color: #009900">byte</span><span style="color: #990000">)</span>
<span style="color: #000000"> 5:</span> <span style="font-weight: bold"><span style="color: #0000FF">go</span></span> pubInstance<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">Publish</span></span><span style="color: #990000">(&lt;</span>AppEngine context<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>http<span style="color: #990000">.</span>ResponseWriter<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;*</span>http<span style="color: #990000">.</span>Request<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>pubnub channel<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>message to publish<span style="color: #990000">&gt;,</span> callbackChannel<span style="color: #990000">,</span> errorChannel<span style="color: #990000">)</span>
<span style="color: #000000"> 6:</span>
<span style="color: #000000"> 7:</span> <span style="font-weight: bold"><span style="color: #000000">handleResult</span></span><span style="color: #990000">(&lt;</span>AppEngine context<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>http<span style="color: #990000">.</span>ResponseWriter<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;*</span>http<span style="color: #990000">.</span>Request<span style="color: #990000">&gt;,</span> <span style="color: #990000">&lt;</span>UUID<span style="color: #990000">&gt;,</span> callbackChannel<span style="color: #990000">,</span> errorChannel<span style="color: #990000">,</span> messaging<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">GetNonSubscribeTimeout</span></span><span style="color: #990000">(),</span> <span style="color: #FF0000">"Publish"</span><span style="color: #990000">)</span></tt></pre></div></div>
<div class="paragraph"><p>Please see this for <a href="#1">[1]</a> for an implementation of <em>Init</em> and this <a href="#2">[2]</a> for <em>handleResult</em>.</p></div>
<div class="paragraph"><p>In the <em>Publish</em> method you need to give same PubNub channel name as the one subscribed (using Javascript). And the message to <em>publish</em>.</p></div>
<div class="paragraph"><p>The <em>callbackChannel</em> is called when we the message is successfully posted. The response is something like this:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="color: #990000">[</span><span style="color: #993399">1</span><span style="color: #990000">,</span><span style="color: #FF0000">"Sent"</span><span style="color: #990000">,</span><span style="color: #FF0000">"14180623236103293"</span><span style="color: #990000">]</span></tt></pre></div></div>
<div class="paragraph"><p>The <em>errorChannel</em> is called when there is an error publishing the message. Like incase of a timeout when publishing the message.</p></div>
</div>
<div class="sect3">
<h4 id="_a_id_2_a_handleresult"><a id="2"></a> handleResult</h4>
<div class="paragraph"><p>This function is a utility function used in the examples below to handle the non Subscribe/Presence response. You would want to adapt it to your own needs. This function reads both the <em>errorChannel</em> and <em>callbackChannel</em> until we get a response on either of the go channels.</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-weight: bold"><span style="color: #0000FF">func</span></span> <span style="font-weight: bold"><span style="color: #000000">handleResult</span></span><span style="color: #990000">(</span>c appengine<span style="color: #990000">.</span>Context<span style="color: #990000">,</span> w http<span style="color: #990000">.</span>ResponseWriter<span style="color: #990000">,</span> r <span style="color: #990000">*</span>http<span style="color: #990000">.</span>Request<span style="color: #990000">,</span> uuid <span style="color: #009900">string</span><span style="color: #990000">,</span> successChannel<span style="color: #990000">,</span> errorChannel <span style="font-weight: bold"><span style="color: #0000FF">chan</span></span> <span style="color: #990000">[]</span><span style="color: #009900">byte</span><span style="color: #990000">,</span> timeoutVal <span style="color: #009900">uint16</span><span style="color: #990000">,</span> action <span style="color: #009900">string</span><span style="color: #990000">)</span> <span style="color: #FF0000">{</span>
<span style="color: #000000"> 2:</span> <span style="font-style: italic"><span style="color: #9A1900">//c := appengine.NewContext(r)</span></span>
<span style="color: #000000"> 3:</span> <span style="font-weight: bold"><span style="color: #0000FF">for</span></span> <span style="color: #FF0000">{</span>
<span style="color: #000000"> 4:</span> <span style="font-weight: bold"><span style="color: #0000FF">select</span></span> <span style="color: #FF0000">{</span>
<span style="color: #000000"> 5:</span>
<span style="color: #000000"> 6:</span> <span style="font-weight: bold"><span style="color: #0000FF">case</span></span> success<span style="color: #990000">,</span> ok <span style="color: #990000">:=</span> <span style="color: #990000">&lt;-</span>successChannel<span style="color: #990000">:</span>
<span style="color: #000000"> 7:</span> <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="color: #990000">!</span>ok <span style="color: #FF0000">{</span>
<span style="color: #000000"> 8:</span> c<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">Infof</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"success!OK"</span><span style="color: #990000">)</span>
<span style="color: #000000"> 9:</span> <span style="font-weight: bold"><span style="color: #0000FF">break</span></span>
<span style="color: #000000"> 10:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 11:</span> <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="color: #009900">string</span><span style="color: #990000">(</span>success<span style="color: #990000">)</span> <span style="color: #990000">!=</span> <span style="color: #FF0000">"[]"</span> <span style="color: #FF0000">{</span>
<span style="color: #000000"> 12:</span> c<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">Infof</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"success:"</span><span style="color: #990000">,</span> <span style="color: #009900">string</span><span style="color: #990000">(</span>success<span style="color: #990000">))</span>
<span style="color: #000000"> 13:</span> <span style="font-weight: bold"><span style="color: #000000">sendResponseToChannel</span></span><span style="color: #990000">(</span>w<span style="color: #990000">,</span> <span style="color: #009900">string</span><span style="color: #990000">(</span>success<span style="color: #990000">),</span> r<span style="color: #990000">,</span> uuid<span style="color: #990000">)</span>
<span style="color: #000000"> 14:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 15:</span>
<span style="color: #000000"> 16:</span> <span style="font-weight: bold"><span style="color: #0000FF">return</span></span>
<span style="color: #000000"> 17:</span> <span style="font-weight: bold"><span style="color: #0000FF">case</span></span> failure<span style="color: #990000">,</span> ok <span style="color: #990000">:=</span> <span style="color: #990000">&lt;-</span>errorChannel<span style="color: #990000">:</span>
<span style="color: #000000"> 18:</span> <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="color: #990000">!</span>ok <span style="color: #FF0000">{</span>
<span style="color: #000000"> 19:</span> c<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">Infof</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"fail1:"</span><span style="color: #990000">,</span> <span style="color: #009900">string</span><span style="color: #990000">(</span><span style="color: #FF0000">"failure"</span><span style="color: #990000">))</span>
<span style="color: #000000"> 20:</span> <span style="font-weight: bold"><span style="color: #0000FF">break</span></span>
<span style="color: #000000"> 21:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 22:</span> <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="color: #009900">string</span><span style="color: #990000">(</span>failure<span style="color: #990000">)</span> <span style="color: #990000">!=</span> <span style="color: #FF0000">"[]"</span> <span style="color: #FF0000">{</span>
<span style="color: #000000"> 23:</span> c<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #000000">Infof</span></span><span style="color: #990000">(</span><span style="color: #FF0000">"fail:"</span><span style="color: #990000">,</span> <span style="color: #009900">string</span><span style="color: #990000">(</span>failure<span style="color: #990000">))</span>
<span style="color: #000000"> 24:</span> <span style="font-weight: bold"><span style="color: #000000">sendResponseToChannel</span></span><span style="color: #990000">(</span>w<span style="color: #990000">,</span> <span style="color: #009900">string</span><span style="color: #990000">(</span>failure<span style="color: #990000">),</span> r<span style="color: #990000">,</span> uuid<span style="color: #990000">)</span>
<span style="color: #000000"> 25:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 26:</span> <span style="font-weight: bold"><span style="color: #0000FF">return</span></span>
<span style="color: #000000"> 27:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 28:</span> <span style="color: #FF0000">}</span>
<span style="color: #000000"> 29:</span> <span style="color: #FF0000">}</span></tt></pre></div></div>
<div class="paragraph"><p>When the message is <em>published</em> the same message will be displayed in the text area on the browser as we are <em>subscribed</em> to the channel.</p></div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_how_to_run">How to run</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_configuration">Configuration:</h3>
<div class="ulist"><ul>
<li>
<p>
Run the following command on the terminal/command prompt.
</p>
</li>
</ul></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #000000"> 1:</span> <span style="font-weight: bold"><span style="color: #0000FF">go</span></span> get github<span style="color: #990000">.</span>com<span style="color: #990000">/</span>pubnub<span style="color: #990000">/</span><span style="font-weight: bold"><span style="color: #0000FF">go</span></span><span style="color: #990000">/</span>messaging</tt></pre></div></div>
<div class="paragraph"><p>This command imports the PubNub&#8217;s Go SDK to the path <em>&lt;Go-Workspace-Folder&gt;/src/pubnub/go</em></p></div>
<div class="ulist"><ul>
<li>
<p>
A <em>.yaml</em> is provided to run the app on the localhost, for your implementation you need create the file for the app as described here:
<a href="https://cloud.google.com/appengine/docs/go/config/appconfig">https://cloud.google.com/appengine/docs/go/config/appconfig</a>
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_run_the_example">Run the example:</h3>
<div class="ulist"><ul>
<li>
<p>
Run the PubNub GAE example using GO on the dev app server using the command
&lt;PATH-to-go_appengine/dev_appserver.py&gt; &lt;Path-to-PubNub-GAE-Folder&gt; --port &lt;port-number-of-your-choice&gt;
</p>
</li>
<li>
<p>
Run <a href="http://localhost:&lt;port-number-of-provided-in-the-command-above&gt">http://localhost:&lt;port-number-of-provided-in-the-command-above&gt</a>;
</p>
</li>
<li>
<p>
On run click the <em>Connect</em> button to connect to the server.
</p>
</li>
<li>
<p>
To <em>subscribe</em> to a channel click the button <em>Subscribe using JS SDK</em>. This will ask for a channel name, on providing a channel name the application will <em>subscribe</em> to the channel.
</p>
</li>
<li>
<p>
<em>Publish</em> a message by clicking the <em>publish</em> button. It will ask for a channel name and the message to publish. On providing both the values the message will be published on the channel.
</p>
</li>
<li>
<p>
The callback message from the <em>Publish</em> call will be displayed in the message area on the browser.
</p>
</li>
<li>
<p>
And so will the message that is received in the <em>Subscribe</em> callback.
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_links">Links:</h2>
<div class="sectionbody">
<div class="paragraph"><p>The complete code is available here:</p></div>
<div class="ulist"><ul>
<li>
<p>
PubNub GAE SDK: git link: <a href="https://github.com/pubnub/go.git">https://github.com/pubnub/go.git</a>
</p>
</li>
<li>
<p>
PubNub GAE SDK: <a href="https://github.com/pubnub/go/tree/master/gae">https://github.com/pubnub/go/tree/master/gae</a>
</p>
</li>
<li>
<p>
PubNub GAE Example: (source for this example): <a href="https://github.com/pubnub/go/tree/master/gae-example">https://github.com/pubnub/go/tree/master/gae-example</a>
</p>
</li>
<li>
<p>
PubNub GAE SDK ReadMe: <a href="https://github.com/pubnub/go/tree/master/gae#quick-implementation-examples">ReadMe</a>.
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2014-12-09 20:33:32 IST
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment