github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/integration/messagebus/glue/README.md (about)

     1  # Glue - Robust Go and Javascript Socket Library
     2  
     3  Glue is a real-time bidirectional socket library. It is a **clean**, **robust** and **efficient** alternative to [socket.io](http://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.
     4  
     5  ## Socket layers
     6  Currently two socket layers are supported:
     7  - **WebSockets** - This is the primary option. They are used if the webbrowser supports WebSockets defined by [RFC 6455](https://tools.ietf.org/html/rfc6455).
     8  - **AjaxSockets** - This socket layer is used as a fallback mode.
     9  
    10  ## Support
    11  Feel free to contribute to this project. Please check the [TODO](TODO.md) file for more information.
    12  
    13  ## Install
    14  ### Client
    15  The client javascript Glue library is located in **[client/dist/glue.js](client/dist/glue.js)**.
    16  
    17  You can use bower to install the client library:
    18  
    19  `bower install --save glue-socket`
    20  
    21  ### Server
    22  Get the source and start hacking.
    23  
    24  `go get github.com/desertbit/glue`
    25  
    26  Import it with:
    27  
    28  ```go
    29  import "github.com/desertbit/glue"
    30  ```
    31  
    32  ## Documentation
    33  ### Client - Javascript Library
    34  A simple call to glue() without any options will establish a socket connection to the same host. A glue socket object is returned.
    35  
    36  ```js
    37  // Create and connect to the server.
    38  // Optional pass a host string and options.
    39  var socket = glue();
    40  ```
    41  
    42  Optional Javascript options which can be passed to Glue:
    43  
    44  ```js
    45  var host = "https://foo.bar";
    46  
    47  var opts = {
    48      // The base URL is appended to the host string. This value has to match with the server value.
    49      baseURL: "/glue/",
    50  
    51      // Force a socket type.
    52      // Values: false, "WebSocket", "AjaxSocket"
    53      forceSocketType: false,
    54  
    55      // Kill the connect attempt after the timeout.
    56      connectTimeout:  10000,
    57  
    58      // If the connection is idle, ping the server to check if the connection is stil alive.
    59      pingInterval:           35000,
    60      // Reconnect if the server did not response with a pong within the timeout.
    61      pingReconnectTimeout:   5000,
    62  
    63      // Whenever to automatically reconnect if the connection was lost.
    64      reconnect:          true,
    65      reconnectDelay:     1000,
    66      reconnectDelayMax:  5000,
    67      // To disable set to 0 (endless).
    68      reconnectAttempts:  10,
    69  
    70      // Reset the send buffer after the timeout.
    71      resetSendBufferTimeout: 10000
    72  };
    73  
    74  // Create and connect to the server.
    75  // Optional pass a host string and options.
    76  var socket = glue(host, opts);
    77  ```
    78  
    79  The glue socket object has following public methods:
    80  
    81  ```js
    82  // version returns the glue socket protocol version.
    83  socket.version();
    84  
    85  // type returns the current used socket type as string.
    86  // Either "WebSocket" or "AjaxSocket".
    87  socket.type();
    88  
    89  // state returns the current socket state as string.
    90  // Following states are available:
    91  //  - "disconnected"
    92  //  - "connecting"
    93  //  - "reconnecting"
    94  //  - "connected"
    95  socket.state();
    96  
    97  // socketID returns the socket's ID.
    98  // This is a cryptographically secure pseudorandom number.
    99  socket.socketID();
   100  
   101  // send a data string to the server.
   102  // One optional discard callback can be passed.
   103  // It is called if the data could not be send to the server.
   104  // The data is passed as first argument to the discard callback.
   105  // returns:
   106  //  1 if immediately send,
   107  //  0 if added to the send queue and
   108  //  -1 if discarded.
   109  socket.send(data, discardCallback);
   110  
   111  // onMessage sets the function which is triggered as soon as a message is received.
   112  socket.onMessage(f);
   113  
   114  // on binds event functions to events.
   115  // This function is equivalent to jQuery's on method syntax.
   116  // Following events are available:
   117  //  - "connected"
   118  //  - "connecting"
   119  //  - "disconnected"
   120  //  - "reconnecting"
   121  //  - "error"
   122  //  - "connect_timeout"
   123  //  - "timeout"
   124  //  - "discard_send_buffer"
   125  socket.on();
   126  
   127  // Reconnect to the server.
   128  // This is ignored if the socket is not disconnected.
   129  // It will reconnect automatically if required.
   130  socket.reconnect();
   131  
   132  // close the socket connection.
   133  socket.close();
   134  
   135  // channel returns the given channel object specified by name
   136  // to communicate in a separate channel than the default one.
   137  socket.channel(name);
   138  ```
   139  
   140  A channel object has following public methods:
   141  
   142  ```js
   143  // onMessage sets the function which is triggered as soon as a message is received.
   144  c.onMessage(f);
   145  
   146  // send a data string to the channel.
   147  // One optional discard callback can be passed.
   148  // It is called if the data could not be send to the server.
   149  // The data is passed as first argument to the discard callback.
   150  // returns:
   151  //  1 if immediately send,
   152  //  0 if added to the send queue and
   153  //  -1 if discarded.
   154  c.send(data, discardCallback);
   155  ```
   156  
   157  ### Server - Go Library
   158  Check the Documentation at [GoDoc.org](https://godoc.org/github.com/desertbit/glue).
   159  
   160  #### Use a custom HTTP multiplexer
   161  If you choose to use a custom HTTP multiplexer, then it is possible to deactivate the automatic HTTP handler registration of glue.
   162  
   163  ```go
   164  // Create a new glue server without configuring and starting the HTTP server.
   165  server := glue.NewServer(glue.Options{
   166      HTTPSocketType: HTTPSocketTypeNone,
   167  })
   168  
   169  //...
   170  ```
   171  
   172  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.
   173  
   174  #### Reading data
   175  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...
   176  
   177  ```go
   178  // ...
   179  
   180  // Discard received data from the main socket channel.
   181  // Hint: Channels have to be discarded separately.
   182  s.DiscardRead()
   183  
   184  // ...
   185  
   186  // Create a channel.
   187  c := s.Channel("golang")
   188  
   189  // Discard received data from a channel.
   190  c.DiscardRead()
   191  ```
   192  
   193  #### Bind custom values to a socket
   194  The socket.Value interface is a placeholder for custom data.
   195  
   196  ```go
   197  type CustomValues struct {
   198      Foo string
   199      Bar int
   200  }
   201  
   202  // ...
   203  
   204  s.Value = &CustomValues{
   205      Foo: "Hello World",
   206      Bar: 900,
   207  }
   208  
   209  // ...
   210  
   211  v, ok := s.Value.(*CustomValues)
   212  if !ok {
   213      // Handle error
   214      return
   215  }
   216  ```
   217  
   218  ### Channels
   219  Channels are separate communication channels from the client to the server of a single socket connections. Multiple separate communication channels can be created:
   220  
   221  Server:
   222  
   223  ```go
   224  // ...
   225  
   226  // Create a channel.
   227  c := s.Channel("golang")
   228  
   229  // Set the channel on read event function.
   230  c.OnRead(func(data string) {
   231      // ...
   232  })
   233  
   234  // Write to the channel.
   235  c.Write("Hello Gophers!")
   236  ```
   237  
   238  Client:
   239  
   240  ```js
   241  var c = socket.channel("golang");
   242  
   243  c.onMessage(function(data) {
   244      console.log(data);
   245  });
   246  
   247  c.send("Hello World");
   248  ```
   249  
   250  ### Broadcasting Messages
   251  
   252  With Glue it is easy to broadcast messages to multiple clients. The Glue Server keeps track of all active connected client sessions.
   253  You can make use of the server **Sockets**, **GetSocket** or **OnNewSocket** methods to implement broadcasting.
   254  
   255  
   256  ## Example
   257  This socket library is very straightforward to use. Check the [sample directory](sample) for more examples.
   258  
   259  ### Client
   260  
   261  ```html
   262  <script>
   263      // Create and connect to the server.
   264      // Optional pass a host string and options.
   265      var socket = glue();
   266  
   267      socket.onMessage(function(data) {
   268          console.log("onMessage: " + data);
   269  
   270          // Echo the message back to the server.
   271          socket.send("echo: " + data);
   272      });
   273  
   274  
   275      socket.on("connected", function() {
   276          console.log("connected");
   277      });
   278  
   279      socket.on("connecting", function() {
   280          console.log("connecting");
   281      });
   282  
   283      socket.on("disconnected", function() {
   284          console.log("disconnected");
   285      });
   286  
   287      socket.on("reconnecting", function() {
   288          console.log("reconnecting");
   289      });
   290  
   291      socket.on("error", function(e, msg) {
   292          console.log("error: " + msg);
   293      });
   294  
   295      socket.on("connect_timeout", function() {
   296          console.log("connect_timeout");
   297      });
   298  
   299      socket.on("timeout", function() {
   300          console.log("timeout");
   301      });
   302  
   303      socket.on("discard_send_buffer", function() {
   304          console.log("some data could not be send and was discarded.");
   305      });
   306  </script>
   307  ```
   308  
   309  ### Server
   310  Read data from the socket with a read event function. Check the sample directory for other ways of reading data from the socket.
   311  
   312  ```go
   313  import (
   314      "log"
   315      "net/http"
   316  
   317      "github.com/desertbit/glue"
   318  )
   319  
   320  func main() {
   321      // Create a new glue server.
   322      server := glue.NewServer(glue.Options{
   323          HTTPListenAddress: ":8080",
   324      })
   325  
   326      // Release the glue server on defer.
   327      // This will block new incoming connections
   328      // and close all current active sockets.
   329      defer server.Release()
   330  
   331      // Set the glue event function to handle new incoming socket connections.
   332      server.OnNewSocket(onNewSocket)
   333  
   334      // Run the glue server.
   335      err := server.Run()
   336      if err != nil {
   337          log.Fatalf("Glue Run: %v", err)
   338      }
   339  }
   340  
   341  func onNewSocket(s *glue.Socket) {
   342      // Set a function which is triggered as soon as the socket is closed.
   343      s.OnClose(func() {
   344          log.Printf("socket closed with remote address: %s", s.RemoteAddr())
   345      })
   346  
   347      // Set a function which is triggered during each received message.
   348      s.OnRead(func(data string) {
   349          // Echo the received data back to the client.
   350          s.Write(data)
   351      })
   352  
   353      // Send a welcome string to the client.
   354      s.Write("Hello Client")
   355  }
   356  ```
   357  
   358  ## Similar Go Projects
   359  - [go-socket.io](https://github.com/googollee/go-socket.io) - socket.io library for golang, a realtime application framework.