Skip to content

adigunhammedolalekan/luna

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Luna Made in Nigeria

Create webSocket servers in a minute

Why

Websocket servers are little bit tricky and not very easy to build, we normally fall back to easy alternative BaaS platform like Firebase or services like Pusher to handle realtime data processing in our apps. Luna aim to make creating WebSocket servers in Golang something anyone can do.

How To

It only takes some few steps to use Luna.

Add luna to your project go get github.com/adigunhammedolalekan/luna

  1. create Luna instance
    g := gin.Default()

    // keyExtractor is a function that should return a
    // unique 'string'. It takes a *http.Request pointer.
    // The intention is to extract a unique Id from request's
    // pointer to set as a unique session key for every
    // webSocket request

	keyExtractor := func(req *http.Request) string {
    		return req.Header.Get("Authorization")
    }

    config := &luna.Config{
        KeyExtractor: keyExtractor,
    }

    l := luna.New(config)

Allow luna to handle websocket connection requests

// Example URL - ws://localhost:port/ws/connect

// Using Go default http stack
http.Handle("/ws/connect", func(w http.ResponseWriter, r *http.Request) {
	// This is a websocket connection, allow luna to handle it
	l.HandleHttpRequest(w, r)
})

// Using Gin
g := gin.Default()
g.GET("/ws/connect", func(context *gin.Context) {
	l.HandleHttpRequest(context.Writer, context.Request)
})
  1. Create json data payload from clients(Js frontend, Android, iOS etc) and use any Websocket client lib to send it
// Example payload
{
	"action" : "subscribe",
	"path" : "/rooms/22/message"
}
// This payload simply subscribe the sender's websocket client to path/channel
// `/rooms/22/message`, after subscription, all messages received by `/rooms/22/message`
// would be sent to this client and every other client that subscribed

// Example message payload
messagePayload = {
	"action" : "message",
	"path" : "/rooms/22/message",
	"data" : {
		"sent_by" : "L3kan",
		"text" : "Hey, there. Luna is awesome",
		"time" : "12:30"
	}
}

**action - can be any of the three option(subscribe, message, unsubscribe), what you use depends on what you want to do
**path - path is where you are sending the message to
**data - is the actual message you are sending
// This payload would send `payload.data` to every client that has subscribed to `/rooms/22/message` channel/path. Amazing!

To stop receiving messages on the client side(i.e UnSubscribe from a channel)
{
    "action" : "unsubscribe",
    "path" : "/rooms/22/message"
}

Although, Luna has a feature that automatically removes idle websocket clients.

As you can see, you can set up a websocket server with few lines of code using Luna.

func main() {

	g := gin.Default()

	// setup keyExtractor
	keyExtractor := func(req *http.Request) string {
    		return req.Header.Get("Authorization")
    }

    // create config
    config := &luna.Config{
        KeyExtractor: keyExtractor,
    }

    // start websocket server
	l := luna.New(config)

    // handle websocket connection requests
	g.GET("/ws/connect", func(c *gin.Context) {
		l.HandleHttpRequest(c.Writer, c.Request)
	})

	// OPTIONAL: Handle a message `payload.data` sent to a particular channel/path
	l.Handle("/rooms/{id}/message", func(c *luna.Context) {
		// Message has been sent to appropriate Websocket clients.
		// do other stuffs here, like saving message into a persistence layer?

        m := &Message{}
        err := json.UnMarshall(c.Data, m)
        if err == nil {
		    Db.Save(m)

		    // you can also use the extracted path
		    // parameters
		    vars := c.Vars
            fmt.Println("Id => ", vars["id"] . (string))
            fmt.Println("Got message from path => " +  c.Path)
        }
	})
}

A full example with a Javascript client can be found in example folder

Console

Web

TODO

  • Add support for FCM - Firebase Cloud Messaging
  • Write more tests

I built a small wrapper lib for android. luna-android

Thanks to @olahol for creating melody.

Follow me on Twitter @L3kanAdigun if you have any question.

Releases

No releases published

Packages

No packages published