github.com/vmware/transport-go@v1.3.4/README.md (about) 1 # Transport. An event bus for Go 2 3  4 [](https://codecov.io/gh/vmware/transport-go) 5 6 Transport is a full stack, simple, fast, expandable application event bus for your applications. It can transport anything you want around your application, 7 as well extend different channels to brokers and destinations. Transport makes it easy to move your bits around localized or distribiuted apps, without worrying 8 about all the wiring. 9 10 ## What does that mean? 11 12 Transport is an event bus, that allows application developers to build components that can talk to one another, really easily. 13 It provides a standardized and simple API, implemented in multiple languages, to allow any individual component inside your 14 applications to talk to one another. 15 16 It really comes to life when you use it to send messages, requests, responses and events around your backend and front-end. 17 Your backend can stream messages to your UI, or other services or agents, as if they were sitting right next to each other, 18 You can build one to one, many to one and many to many topologies with ease. 19 20 Channels can be extended to major brokers like Kafka or RabbitMQ, so Transport becomes an 'on/off-ramp' for your main sources of truth. 21 22 ### Watch this quick video for an overview 23 24 [](https://www.youtube.com/watch?v=k-KDPtCQyls) 25 26 ### Transport for Go also comes with plank 27 28 **plank** is a micro platform for building just about anything you can think of, it exposes RESTful and AsyncAPI & Pub/Sub endpoints 29 for services that can do just about anything. [Read more about `plank`](https://github.com/vmware/transport-go/tree/main/plank) 30 31 --- 32 33 ## Getting Started 34 35 ### [View All Transport (Golang) Documentation](https://transport-bus.io/golang) 36 37 #### Other versions of Transport 38 39 - [Transport TypeScript](https://github.com/vmware/transport-typescript) 40 - [Transport Java](https://github.com/vmware/transport-java) 41 42 ### Transport Site 43 [https://transport-bus.io](https://transport-bus.io) 44 45 --- 46 ## Quick Start 47 48 Install transport 49 50 ```go 51 go get -u github.com/vmware/transport-go 52 ``` 53 54 To create an instance of the bus 55 56 ```go 57 import "github.com/vmware/transport-go/bus" 58 59 var transport = bus.GetBus() 60 ``` 61 > Transport is a singleton, there is (should) only ever a single instance of the bus in your application. 62 63 ---- 64 65 ## Managing / Creating Channels 66 67 The `ChannelManager` interface on the `EventBus` interface facilitates all Channel operations. 68 69 ```go 70 channelManager := transport.GetChannelManager() 71 ``` 72 73 ### Creating Channels 74 75 The `CreateChannel` method will create a new channel with the name "some-channel". It will return a pointer to a 76 `Channel` object. You don't need to hold on to that pointer if you don't want to. The channel will still exist. 77 78 ```go 79 channel := channelManager.CreateChanel("some-channel") 80 ``` 81 82 ## Simple Example 83 84 A simple ping pong looks a little like this. 85 86 ```go 87 // listen for a single request on 'some-channel' 88 ts := bus.GetBus() 89 channel := "some-channel" 90 ts.GetChannelManager().CreateChannel(channel) 91 92 // listen for a single request on 'some-channel' 93 requestHandler, _ := ts.ListenRequestStream(channel) 94 requestHandler.Handle( 95 func(msg *model.Message) { 96 pingContent := msg.Payload.(string) 97 fmt.Printf("\nPing: %s\n", pingContent) 98 99 // send a response back. 100 ts.SendResponseMessage(channel, pingContent, msg.DestinationId) 101 }, 102 func(err error) { 103 // something went wrong... 104 }) 105 106 // send a request to 'some-channel' and handle a single response 107 responseHandler, _ := ts.RequestOnce(channel, "Woo!") 108 responseHandler.Handle( 109 func(msg *model.Message) { 110 fmt.Printf("Pong: %s\n", msg.Payload.(string)) 111 }, 112 func(err error) { 113 // something went wrong... 114 }) 115 // fire the request. 116 responseHandler.Fire() 117 ``` 118 119 This will output: 120 121 ```text 122 🌈 Transport booted with id [e495e5d5-2b72-46dd-8013-d49049bd4800] 123 Ping: Woo! 124 Pong: Woo! 125 ``` 126 --- 127 ## Connecting to a message broker and using galactic channels 128 129 You can see this all working live in some of our interactive demos for [Transport TypeScript](https://transport-bus.io/ts/examples/joke-service). 130 it shows Transport acting as both client and server, in which we use [`plank`](https://github.com/vmware/transport-go/tree/main/plank) to run 131 services, and the UI subscribes to those services and talks to them. 132 133 We have a live and running instance of [`plank`](https://github.com/vmware/transport-go/tree/main/plank) operating at 134 [transport-bus.io](https://transport-bus.io). You can try the example code below to use the sample 135 [simple stream service](https://github.com/vmware/transport-go/blob/main/plank/services/simple-stream-service.go) and 136 see how simple it is for yourself. 137 138 ### Simple Stream Example 139 140 ```go 141 // get a pointer to the bus. 142 b := bus.GetBus() 143 144 // get a pointer to the channel manager 145 cm := b.GetChannelManager() 146 147 // create a broker connector config and connect to 148 // transport-bus.io over WebSocket using TLS. 149 config := &bridge.BrokerConnectorConfig{ 150 Username: "guest", // not required for demo, but our API requires it. 151 Password: "guest", // ^^ same. 152 ServerAddr: "transport-bus.io", // our live broker running plank and demo services. 153 UseWS: true, // connect over websockets 154 WebSocketConfig: &bridge.WebSocketConfig{ // configure websocket 155 WSPath: "/ws", // websocket endpoint 156 UseTLS: true, 157 // use TLS/HTTPS. When using TLS, you can supply your own TLSConfig value, or we can 158 // generate a basic one for you if you leave TLSConfig empty. In most cases, 159 // you won't need to supply one. 160 }} 161 162 // connect to transport-bus.io demo broker 163 c, err := b.ConnectBroker(config) 164 if err != nil { 165 utils.Log.Fatalf("unable to connect to transport-bus.io, error: %v", err.Error()) 166 } 167 168 // create a local channel on the bus. 169 myLocalChan := "my-stream" 170 cm.CreateChannel(myLocalChan) 171 172 // listen to stream of messages coming in on channel, a handler is returned 173 // that allows you to add in lambdas that handle your success messages, and your errors. 174 handler, _ := b.ListenStream(myLocalChan) 175 176 // mark our local 'my-stream' myLocalChan as galactic and map it to our connection and 177 // the /topic/simple-stream service 178 err = cm.MarkChannelAsGalactic(myLocalChan, "/topic/simple-stream", c) 179 if err != nil { 180 utils.Log.Fatalf("unable to map local channel to broker destination: %e", err) 181 } 182 183 // collect the streamed values in a slice 184 var streamedValues []string 185 186 // create a wait group that will wait 10 times before completing. 187 var wg sync.WaitGroup 188 wg.Add(10) 189 190 // keep listening 191 handler.Handle( 192 func(msg *model.Message) { 193 194 // unmarshal the message payload into a model.Response object 195 // this is a wrapper transport uses when being used as a server, 196 // it encapsulates a rich set of data about the message, 197 // but you only really care about the payload (body) 198 r := &model.Response{} 199 d := msg.Payload.([]byte) 200 err := json.Unmarshal(d, &r) 201 if err != nil { 202 utils.Log.Errorf("error unmarshalling request: %v", err.Error()) 203 return 204 } 205 // the value we want is in the payload of our model.Response 206 value := r.Payload.(string) 207 208 // log it and save it to our streamedValues 209 utils.Log.Infof("stream ticked: %s", value) 210 streamedValues = append(streamedValues, value) 211 wg.Done() 212 }, 213 func(err error) { 214 utils.Log.Errorf("error received on channel: %e", err) 215 }) 216 217 // wait for 10 ticks of the stream, then we're done. 218 wg.Wait() 219 220 // close our handler, we're done. 221 handler.Close() 222 223 // mark channel as local (unsubscribe from all mappings) 224 err = cm.MarkChannelAsLocal(myLocalChan) 225 if err != nil { 226 utils.Log.Fatalf("unable to unsubscribe, error: %e", err) 227 } 228 229 // disconnect 230 err = c.Disconnect() 231 if err != nil { 232 utils.Log.Fatalf("unable to disconnect, error: %e", err) 233 } 234 235 // return what we got from the stream. 236 return streamedValues 237 ``` 238 239 You can [see this simple example here](https://github.com/vmware/transport-go/blob/main/examples/simple_stream.go) 240 241 242 ### [Read More Golang Documentation](https://transport-bus.io/golang) 243 244 --- 245 246 ### [What is `plank`?](https://github.com/vmware/transport-go/tree/main/plank) 247 248 `plank` is 'just enough' of a platform for building just about anything you want. Run RESTful and AsyncAPIs with the 249 same code, build simple or complex services that can be exposed to any client in any manner. Talk over WebSockets and pub/sub 250 and streaming, or call the same APIs via REST mappings. `plank` can do it all. It's tiny, super-fast and runs on any platform. Runs in 251 just a few megabytes of memory, and can be compiled down to the same. It can be used for micro-services, daemons, agents, 252 local UI helper applications... anything! 253 254 `plank` is only available in transport-go 255 256 [Take a look at plank](https://github.com/vmware/transport-go/tree/main/plank) 257 258 --- 259 ## Contributing 260 261 The transport-go project team welcomes contributions from the community. Before you start working with transport-go, please 262 read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be 263 signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on 264 as an open-source patch. For more detailed information, refer to [CONTRIBUTING.md](CONTRIBUTING.md). 265 266 ## License 267 BSD-2-Clause 268 269 Copyright (c) 2016-2021, VMware, Inc. 270 271 Redistribution and use in source and binary forms, with or without 272 modification, are permitted provided that the following conditions are met: 273 274 1. Redistributions of source code must retain the above copyright notice, this 275 list of conditions and the following disclaimer. 276 2. Redistributions in binary form must reproduce the above copyright notice, 277 this list of conditions and the following disclaimer in the documentation 278 and/or other materials provided with the distribution. 279 280 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 281 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 282 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 283 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 284 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 285 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 286 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 287 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 288 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 289 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.