Glue - Robust Go and Javascript Socket Library (Alternative to Socket.io)

Related tags

glue
Overview

Glue - Robust Go and Javascript Socket Library

GoDoc Go Report Card Join the chat at https://gitter.im/desertbit/glue

Glue is a real-time bidirectional socket library. It is a clean, robust and efficient alternative to socket.io. This library is designed to connect webbrowsers with a go-backend in a simple way. It automatically detects supported socket layers and chooses the most suitable one. This library handles automatic reconnections on disconnections and handles caching to bridge those disconnections. The server implementation is thread-safe and stable. The API is fixed and there won't be any breaking API changes.

Socket layers

Currently two socket layers are supported:

  • WebSockets - This is the primary option. They are used if the webbrowser supports WebSockets defined by RFC 6455.
  • AjaxSockets - This socket layer is used as a fallback mode.

Support

Feel free to contribute to this project. Please check the TODO file for more information.

Install

Client

The client javascript Glue library is located in client/dist/glue.js.

You can use bower to install the client library:

bower install --save glue-socket

Server

Get the source and start hacking.

go get github.com/desertbit/glue

Import it with:

import "github.com/desertbit/glue"

Documentation

Client - Javascript Library

A simple call to glue() without any options will establish a socket connection to the same host. A glue socket object is returned.

// Create and connect to the server.
// Optional pass a host string and options.
var socket = glue();

Optional Javascript options which can be passed to Glue:

var host = "https://foo.bar";

var opts = {
    // The base URL is appended to the host string. This value has to match with the server value.
    baseURL: "/glue/",

    // Force a socket type.
    // Values: false, "WebSocket", "AjaxSocket"
    forceSocketType: false,

    // Kill the connect attempt after the timeout.
    connectTimeout:  10000,

    // If the connection is idle, ping the server to check if the connection is stil alive.
    pingInterval:           35000,
    // Reconnect if the server did not response with a pong within the timeout.
    pingReconnectTimeout:   5000,

    // Whenever to automatically reconnect if the connection was lost.
    reconnect:          true,
    reconnectDelay:     1000,
    reconnectDelayMax:  5000,
    // To disable set to 0 (endless).
    reconnectAttempts:  10,

    // Reset the send buffer after the timeout.
    resetSendBufferTimeout: 10000
};

// Create and connect to the server.
// Optional pass a host string and options.
var socket = glue(host, opts);

The glue socket object has following public methods:

// version returns the glue socket protocol version.
socket.version();

// type returns the current used socket type as string.
// Either "WebSocket" or "AjaxSocket".
socket.type();

// state returns the current socket state as string.
// Following states are available:
//  - "disconnected"
//  - "connecting"
//  - "reconnecting"
//  - "connected"
socket.state();

// socketID returns the socket's ID.
// This is a cryptographically secure pseudorandom number.
socket.socketID();

// send a data string to the server.
// One optional discard callback can be passed.
// It is called if the data could not be send to the server.
// The data is passed as first argument to the discard callback.
// returns:
//  1 if immediately send,
//  0 if added to the send queue and
//  -1 if discarded.
socket.send(data, discardCallback);

// onMessage sets the function which is triggered as soon as a message is received.
socket.onMessage(f);

// on binds event functions to events.
// This function is equivalent to jQuery's on method syntax.
// Following events are available:
//  - "connected"
//  - "connecting"
//  - "disconnected"
//  - "reconnecting"
//  - "error"
//  - "connect_timeout"
//  - "timeout"
//  - "discard_send_buffer"
socket.on();

// Reconnect to the server.
// This is ignored if the socket is not disconnected.
// It will reconnect automatically if required.
socket.reconnect();

// close the socket connection.
socket.close();

// channel returns the given channel object specified by name
// to communicate in a separate channel than the default one.
socket.channel(name);

A channel object has following public methods:

// onMessage sets the function which is triggered as soon as a message is received.
c.onMessage(f);

// send a data string to the channel.
// One optional discard callback can be passed.
// It is called if the data could not be send to the server.
// The data is passed as first argument to the discard callback.
// returns:
//  1 if immediately send,
//  0 if added to the send queue and
//  -1 if discarded.
c.send(data, discardCallback);

Server - Go Library

Check the Documentation at GoDoc.org.

Use a custom HTTP multiplexer

If you choose to use a custom HTTP multiplexer, then it is possible to deactivate the automatic HTTP handler registration of glue.

// Create a new glue server without configuring and starting the HTTP server.
server := glue.NewServer(glue.Options{
    HTTPSocketType: HTTPSocketTypeNone,
})

//...

The glue server implements the ServeHTTP method of the HTTP Handler interface of the http package. Use this to register the glue HTTP handler with a custom multiplexer. Be aware, that the URL of the custom HTTP handler has to match with the glue HTTPHandleURL options string.

Reading data

Data has to be read from the socket and each channel. If you don't require to read data from the socket or a channel, then discard received data with the DiscardRead() method. If received data is not discarded, then the read buffer will block as soon as it is full, which will also block the keep-alive mechanism of the socket. The result would be a closed socket...

// ...

// Discard received data from the main socket channel.
// Hint: Channels have to be discarded separately.
s.DiscardRead()

// ...

// Create a channel.
c := s.Channel("golang")

// Discard received data from a channel.
c.DiscardRead()

Bind custom values to a socket

The socket.Value interface is a placeholder for custom data.

type CustomValues struct {
    Foo string
    Bar int
}

// ...

s.Value = &CustomValues{
    Foo: "Hello World",
    Bar: 900,
}

// ...

v, ok := s.Value.(*CustomValues)
if !ok {
    // Handle error
    return
}

Channels

Channels are separate communication channels from the client to the server of a single socket connections. Multiple separate communication channels can be created:

Server:

// ...

// Create a channel.
c := s.Channel("golang")

// Set the channel on read event function.
c.OnRead(func(data string) {
    // ...
})

// Write to the channel.
c.Write("Hello Gophers!")

Client:

var c = socket.channel("golang");

c.onMessage(function(data) {
    console.log(data);
});

c.send("Hello World");

Broadcasting Messages

With Glue it is easy to broadcast messages to multiple clients. The Glue Server keeps track of all active connected client sessions. You can make use of the server Sockets, GetSocket or OnNewSocket methods to implement broadcasting.

Example

This socket library is very straightforward to use. Check the sample directory for more examples.

Client

<script>
    // Create and connect to the server.
    // Optional pass a host string and options.
    var socket = glue();

    socket.onMessage(function(data) {
        console.log("onMessage: " + data);

        // Echo the message back to the server.
        socket.send("echo: " + data);
    });


    socket.on("connected", function() {
        console.log("connected");
    });

    socket.on("connecting", function() {
        console.log("connecting");
    });

    socket.on("disconnected", function() {
        console.log("disconnected");
    });

    socket.on("reconnecting", function() {
        console.log("reconnecting");
    });

    socket.on("error", function(e, msg) {
        console.log("error: " + msg);
    });

    socket.on("connect_timeout", function() {
        console.log("connect_timeout");
    });

    socket.on("timeout", function() {
        console.log("timeout");
    });

    socket.on("discard_send_buffer", function() {
        console.log("some data could not be send and was discarded.");
    });
</script>

Server

Read data from the socket with a read event function. Check the sample directory for other ways of reading data from the socket.

import (
    "log"
    "net/http"

    "github.com/desertbit/glue"
)

func main() {
    // Create a new glue server.
    server := glue.NewServer(glue.Options{
        HTTPListenAddress: ":8080",
    })

    // Release the glue server on defer.
    // This will block new incoming connections
    // and close all current active sockets.
    defer server.Release()

    // Set the glue event function to handle new incoming socket connections.
    server.OnNewSocket(onNewSocket)

    // Run the glue server.
    err := server.Run()
    if err != nil {
        log.Fatalf("Glue Run: %v", err)
    }
}

func onNewSocket(s *glue.Socket) {
    // Set a function which is triggered as soon as the socket is closed.
    s.OnClose(func() {
        log.Printf("socket closed with remote address: %s", s.RemoteAddr())
    })

    // Set a function which is triggered during each received message.
    s.OnRead(func(data string) {
        // Echo the received data back to the client.
        s.Write(data)
    })

    // Send a welcome string to the client.
    s.Write("Hello Client")
}

Similar Go Projects

  • go-socket.io - socket.io library for golang, a realtime application framework.
Issues
  • Exposing request to the session

    Exposing request to the session

    Why

    • For token based authentication, and getting the current user from the request
    • For access to request params ...
    opened by osiloke 7
  • Add MIT dual licence

    Add MIT dual licence

    I'd like to use this in a project, but there are several issues related to the GPL that could cause trouble when the js code is distributed in a web app. Would it be possible to add a dual MIT license to this code?

    opened by conejo 7
  • How To Broadcast

    How To Broadcast

    I don't see any documentation about this? Will simply send to a channel broadcast the message to all clients in that channel?

    opened by JesusIslam 4
  • Update socket.go

    Update socket.go

    Remove dirty hack, because gorilla websocket does not use 1001 error code

    It was used here:

        case CloseMessage:
            c.WriteControl(CloseMessage, []byte{}, time.Now().Add(writeWait))
            closeCode := CloseNoStatusReceived
            closeText := ""
            if len(payload) >= 2 {
                closeCode = int(binary.BigEndian.Uint16(payload))
                closeText = string(payload[2:])
            }
            return noFrame, &CloseError{Code: closeCode, Text: closeText}
        }
    
    opened by ZloyDyadka 4
  • Nix jQuery Dependency

    Nix jQuery Dependency

    This is a great, no nonsense, library. Thanks for creating it! With that said can you possibly entertain the idea of getting rid of the jquery dependency? Jquery is great and all but it's too much fluff when all you need is the ajax portion. At least if continuing to use a dependency maybe change to axios or fetch or something that is specifically created for the job needed.

    Thanks!

    opened by u382514 3
  • added SetLogOutput and prefixed formatter

    added SetLogOutput and prefixed formatter

    SetLogOutput allows adding an io.Writer as the loggers output destination. This is useful for logging into a file or into a stream multiplexer. The prefixed formatter allows adding prefixes to log messages, which is helpful for debugging. Also it has a very nice output.

    opened by dreadl0ck 2
  • "github.com/Sirupsen/logrus" organization name renamed to lowercase

    The sirupsen organization has been renamed to lowercase "github.com/sirupsen/logrus". This causes issues when trying to resolve this project's dependencies.

    Imports should be search-replaced to use lower-case "sirupsen"

    opened by smyrman 2
  • Cannot install on Go 1.8

    Cannot install on Go 1.8

    Trying to set it up on OSX 10.11.6, Go version 1.8 and getting error:

    go get github.com/desertbit/glue
    # github.com/desertbit/glue/backend/sockets/websocket
    glue/backend/sockets/websocket/socket.go:156: undefined: websocket.CloseError
    

    Tried it on 1.7.4 on a Ubuntu 14.04 VPS and it installed without problem.

    Maybe it's a problem due to the package having the same name as gorilla/websocket package?

    opened by ripexz 1
  • Add a Gitter chat badge to README.md

    Add a Gitter chat badge to README.md

    desertbit/glue now has a Chat Room on Gitter

    @m4ng0squ4sh has just created a chat room. You can visit it here: https://gitter.im/desertbit/glue.

    This pull-request adds this badge to your README.md:

    Gitter

    If my aim is a little off, please let me know.

    Happy chatting.

    PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.

    opened by gitter-badger 0
  • Handle Sirupsen -> sirupsen organizaiton rename

    Handle Sirupsen -> sirupsen organizaiton rename

    This commit fixes issue #11 by renaming all imports to rely on the new lower-case import for logrus:

    • github.com/sirupsen/logrus
    opened by smyrman 0
  • fix typo

    fix typo

    Fix a typo in comment

    opened by hnx116 0
  • Fixes #14 update file header to match license

    Fixes #14 update file header to match license

    Missed this the first round. File headers needed updated as well.

    opened by leebradley 1
  • baseUrl Value

    baseUrl Value

    When I changed the base 'baseURL' on the js side and http handle functions pattern on the go side, js client can not connect to server. Its about the string length. It can not connect to server if string length longer than 4.

    opened by ProgramYazar 2
  • Split / Subrepo Javascript Client

    Split / Subrepo Javascript Client

    Hi,

    I was wondering if it would be possible to split out the client library so that I can then be published to NPM and other Javascript package management tools and the bought in as a modern dependency?

    Thanks.

    opened by bobbysciacchitano 2
  • Broadcast Rooms

    Broadcast Rooms

    Discuss the idea of broadcasting rooms and implement this feature.

    opened by r0l1 1
  • A Go Client

    A Go Client

    It would be nice to have a Go client that can be used to communicate from another go process/app.

    opened by hamin 1
Owner
DesertBit
DesertBit Projects
DesertBit
Glue - Robust Go and Javascript Socket Library (Alternative to Socket.io)

Glue - Robust Go and Javascript Socket Library Glue is a real-time bidirectional socket library. It is a clean, robust and efficient alternative to so

DesertBit 379 Jun 30, 2021
socket.io library for golang, a realtime application framework.

go-socket.io go-socket.io is library an implementation of Socket.IO in Golang, which is a realtime application framework. Current this library support

Googol Lee 4.2k Jul 23, 2021
goczmq is a golang wrapper for CZMQ.

goczmq Introduction A golang interface to the CZMQ v4.2 API. Install Dependencies libsodium libzmq czmq For CZMQ master go get github.com/zeromq/goczm

The ZeroMQ project 452 Jul 12, 2021
Machinery is an asynchronous task queue/job queue based on distributed message passing.

Machinery Machinery is an asynchronous task queue/job queue based on distributed message passing. V2 Experiment First Steps Configuration Lock Broker

Richard Knop 5.4k Jul 15, 2021
websocket based messaging server written in golang

Guble Messaging Server Guble is a simple user-facing messaging and data replication server written in Go. Overview Guble is in an early state (release

Sebastian Mancke 148 Jun 3, 2021
golang long polling library. Makes web pub-sub easy via HTTP long-poll server :smiley: :coffee: :computer:

golongpoll Golang long polling library. Makes web pub-sub easy via an HTTP long-poll server. New in v1.1 Deprecated CreateManager and CreateCustomMana

J Cuga 561 Jul 24, 2021
A Go interface to ZeroMQ version 2

A Go interface to ZeroMQ version 2. Requires ZeroMQ version 2.1 or 2.2 For ZeroMQ version 4, see: http://github.com/pebbe/zmq4 For ZeroMQ version 3, s

Peter Kleiweg 18 May 26, 2021
ðŸ’ĻA well crafted go packages that help you build robust, reliable, maintainable microservices.

Hippo A Microservices Toolkit. Hippo is a collection of well crafted go packages that help you build robust, reliable, maintainable microservices. It

Ahmed 137 Jul 22, 2021
ðŸ’Ļ A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver A Real Time Messaging Server. Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime

Ahmed 1.1k Jul 17, 2021
dque is a fast, embedded, durable queue for Go

dque - a fast embedded durable queue for Go dque is: persistent -- survives program restarts scalable -- not limited by your RAM, but by your disk spa

Jon Carlson 646 Jul 23, 2021
🐇 Easy to use socket lib for Golang

Hare Sockets ?? Hare is a user-friendly lib for sockets in Golang. You can send and listen to TCP connections with a few lines of code. Contents Insta

Leonardo Lima 27 Jul 4, 2021
A user friendly RabbitMQ library written in Golang.

TurboCookedRabbit A user friendly RabbitMQ library written in Golang to help use streadway/amqp. Based on my work found at CookedRabbit. Work Recently

Tristan (HouseCat) Hyams 80 Jul 21, 2021
A wrapper of streadway/amqp that provides reconnection logic and sane defaults

go-rabbitmq Wrapper of streadway/amqp that provides reconnection logic and sane defaults. Hit the project with a star if you find it useful ⭐ Supporte

Lane Wagner 72 Jul 23, 2021
Inspr is an application mesh for simple, fast and secure development of distributed applications.

Inspr is an engine for running distributed applications, using multiple communication patterns such as pub sub and more, focused on type consistency a

Inspr 37 Jul 22, 2021