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.