func runSender(qnum int) { ltag := tag + "-runsender" ll.Printf("%stag:%s connsess:%s start qnum:%d\n", exampid, ltag, sngecomm.Lcs, qnum) // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s error:%s\n", exampid, ltag, sngecomm.Lcs, e.Error()) // Handle this ...... } // sendMessages(conn, qnum, n) ll.Printf("%stag:%s connsess:%s sends_complete qnum:%d\n", exampid, ltag, conn.Session(), qnum) // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s error:%s\n", exampid, ltag, conn.Session(), e.Error()) // Handle this ...... } sngecomm.ShowStats(exampid, "send_"+fmt.Sprintf("%d", qnum), conn) wgs.Done() }
func runReceiver(qnum int) { ltag := tag + "-runreceiver" ll.Printf("%stag:%s connsess:%s start qnum:%d\n", exampid, ltag, sngecomm.Lcs, qnum) // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s error:%s\n", exampid, ltag, sngecomm.Lcs, e.Error()) // Handle this ...... } // conn.SetSubChanCap(senv.SubChanCap()) // Experiment with this value, YMMV // Receives receiveMessages(conn, qnum, n) ll.Printf("%stag:%s connsess:%s receives_complete qnum:%d\n", exampid, ltag, conn.Session(), qnum) // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s error:%s\n", exampid, ltag, conn.Session(), e.Error()) // Handle this ...... } sngecomm.ShowStats(exampid, "recv_"+fmt.Sprintf("%d", qnum), conn) wgr.Done() }
/* closeSconn closes a stompngo Connection. */ func closeSconn(n net.Conn, conn *stompngo.Connection) { ltag := tag + "-closesconn" // Standard example disconnect sequence e := sngecomm.CommonDisconnect(n, conn, exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s disconnect_error error:%s\n", exampid, ltag, conn.Session(), e.Error()) // Handle this ...... } return }
// Connect to a STOMP broker, publish some messages and disconnect. func main() { st := time.Now() // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // *NOTE* application specific functionaltiy starts here! sh := stompngo.Headers{"destination", sngecomm.Dest()} ll.Printf("%stag:%s connsess:%s destination dest:%s\n", exampid, tag, conn.Session(), sngecomm.Dest()) if senv.Persistent() { sh = sh.Add("persistent", "true") } ms := exampid + "message: " for i := 1; i <= senv.Nmsgs(); i++ { mse := ms + fmt.Sprintf("%d", i) ll.Printf("%stag:%s connsess:%s main_sending mse:~%s~\n", exampid, tag, conn.Session(), mse) e := conn.Send(sh, mse) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_send_complete mse:~%s~\n", exampid, tag, conn.Session(), mse) time.Sleep(100 * time.Millisecond) } // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker, send some messages and disconnect. func main() { st := time.Now() // Standard example connect sequence // Use AMQ port here n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // Suppress content length here, so JMS will treat this as a 'text' message. sh := stompngo.Headers{"destination", "jms.queue.exampleQueue"} if os.Getenv("STOMP_NOSCL") != "true" { sh = sh.Add("suppress-content-length", "true") } if senv.Persistent() { sh = sh.Add("persistent", "true") } ms := exampid + " message: " for i := 1; i <= nmsgs; i++ { mse := ms + fmt.Sprintf("%d", i) e := conn.Send(sh, mse) if e != nil { ll.Fatalf("%stag:%s connsess:%s send_error error:%v\n", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s send_complete\n", exampid, tag, conn.Session()) } // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_disconnect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker, subscribe and receive some messages and disconnect. func main() { st := time.Now() // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } session = conn.Session() //****************** nqs := sngecomm.Nqs() for qn := 1; qn <= nqs; qn++ { runNextQueue(qn, conn) } //****************** ll.Printf("%stag:%s connsess:%s start_drain_receives\n", exampid, tag, session) for _, v := range qcb { _ = <-v } ll.Printf("%stag:%s connsess:%s end_drain_receives\n", exampid, tag, session) // Standard example disconnect sequence if dodisc { e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, session, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s disconnect_receipt:%v\n", exampid, tag, session, conn.DisconnectReceipt) } else { ll.Printf("%stag:%s connsess:%s skipping_disconnect\n", exampid, tag, session) } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, session, time.Now().Sub(st)) }
// Connect to a STOMP broker using TLS and disconnect. func main() { st := time.Now() ll.Printf("%stag:%s connsess:%s starts\n", exampid, tag, sngecomm.Lcs) // TLS Configuration. tc = new(tls.Config) tc.InsecureSkipVerify = true // Do *not* check the server's certificate // Usually one will use the default cipher suites that go provides. // However, if a custom cipher squite list is needed/required this // is how it is accomplished. if sngecomm.UseCustomCiphers() { // Set custom cipher suite list tc.CipherSuites = append(tc.CipherSuites, sngecomm.CustomCiphers()...) } // Standard example TLS connect sequence n, conn, e := sngecomm.CommonTLSConnect(exampid, tag, ll, tc) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } nc := n.(*tls.Conn) sngecomm.DumpTLSConfig(exampid, tc, nc) // *NOTE* application specific functionaltiy starts here! // For you to add. // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker using TLS and disconnect. func main() { st := time.Now() ll.Printf("%stag:%s connsess:%s starts\n", exampid, tag, sngecomm.Lcs) // TLS Configuration. This configuration assumes that: // a) The server used does *not* require client certificates // b) This client has no need to authenticate the server // Note that the tls.Config structure can be modified to support any // authentication scheme, including two-way/mutual authentication. Examples // are provided elsewhere in this project. tc = new(tls.Config) tc.InsecureSkipVerify = true // Do *not* check the server's certificate // Standard example TLS connect sequence n, conn, e := sngecomm.CommonTLSConnect(exampid, tag, ll, tc) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } nc := n.(*tls.Conn) sngecomm.DumpTLSConfig(exampid, tc, nc) // *NOTE* application specific functionaltiy starts here! // For you to add. // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker and disconnect. func main() { st := time.Now() // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { if conn != nil { ll.Printf("%stag%s connsess:%s main_on_connect error Connect Response headers:%v body%s\n", exampid, tag, conn.Session(), conn.ConnectResponse.Headers, string(conn.ConnectResponse.Body)) } ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } ll.Printf("%stag%s connsess:%s Connect Response headers:%v body%s\n", exampid, tag, conn.Session(), conn.ConnectResponse.Headers, string(conn.ConnectResponse.Body)) // *NOTE* application specific functionaltiy starts here! // For you to add. // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
func startReceivers(qn int) { ltag := tag + "-startreceivers" ll.Printf("%stag:%s connsess:%s starts qn:%d\n", exampid, ltag, sngecomm.Lcs, qn) // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s on_connect error:%v", exampid, ltag, sngecomm.Lcs, e.Error()) // Handle this ...... } nmsgs := senv.Nmsgs() // get message count ll.Printf("%stag:%s connsess:%s message_count nmsgs:%d qn:%d\n", exampid, ltag, conn.Session(), nmsgs, qn) for i := 1; i <= qn; i++ { // all queues wgr.Add(1) go receiver(conn, i, nmsgs) } ll.Printf("%stag:%s connsess:%s starts_done\n", exampid, ltag, conn.Session()) wgr.Wait() // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, ltag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s on_disconnect error:%v", exampid, ltag, conn.Session(), e.Error()) // Handle this ...... } sngecomm.ShowStats(exampid, ltag, conn) wga.Done() }
func main() { // Make sure that the queue used by this example do not exist, or are // empty. // Following is a lengthy piece of code. Read it striaght from top // to bottom. There is zero complex logic here. // What this code will do: // Phase 1: // - Connect to a broker // - Verify a connection spec level // - Send a single message to the specified queue on that broker // - Disconnect from that broker // // Phase 2: // - Reconnect to the same broker // - Subscribe to the specified queue, using "ack:client-individual" // - Receive a single message // - Send an ACK, asking for a receipt //************************************************************************** // - Receive a RECEIPT // The point of this exercise. // - Show data from the RECEIPT and verify it // The point of this exercise. //************************************************************************** // - Disconnect from the broker // Start st := time.Now() // **************************************** Phase 1 // Set up the connection. // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // **************************************** // App logic here ..... d := sngecomm.Dest() ll.Printf("%stag:%s connsess:%s destination:%v\n", exampid, tag, conn.Session(), d) // **************************************** // Send exactly one message. sh := stompngo.Headers{"destination", sngecomm.Dest()} if senv.Persistent() { sh = sh.Add("persistent", "true") } m := exampid + " message: " t := m + "1" ll.Printf("%stag:%s connsess:%s sending_now body:%v\n", exampid, tag, conn.Session(), t) e = conn.Send(sh, t) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_bad_send error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s send_complete body:%v\n", exampid, tag, conn.Session(), t) // **************************************** // Disconnect from the Stomp server // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } // **************************************** Phase 2 // Standard example connect sequence n, conn, e = sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // **************************************** // Subscribe here id := stompngo.Uuid() // Get the "subscribe channel" sc := sngecomm.HandleSubscribe(conn, d, id, "client-individual") ll.Printf("%stag:%s connsess:%s stomp_subscribe_complete\n", exampid, tag, conn.Session()) // Get data from the broker var md stompngo.MessageData // A message data instance select { case md = <-sc: case md = <-conn.MessageData: // This would be contain an ERROR or RECEIPT frame. Both are unexpected // in this example. ll.Fatalf("%stag:%s connsess:%s bad_frame md:%v", exampid, tag, conn.Session(), md) // Handle this ...... } ll.Printf("%stag:%s connsess:%s channel_read_complete\n", exampid, tag, conn.Session()) // MessageData has two components: // a) a Message struct // b) an Error value. Check the error value as usual if md.Error != nil { ll.Fatalf("%stag:%s connsess:%s message_error md:%v", exampid, tag, conn.Session(), md.Error) // Handle this ...... } ll.Printf("%stag:%s connsess:%s read_message_COMMAND command:%s\n", exampid, tag, conn.Session(), md.Message.Command) ll.Printf("%stag:%s connsess:%s read_message_HEADERS headers:%s\n", exampid, tag, conn.Session(), md.Message.Headers) ll.Printf("%stag:%s connsess:%s read_message_BODY body:%s\n", exampid, tag, conn.Session(), string(md.Message.Body)) // Here we need to send an ACK. Required Headers are different between // a 1.1 and a 1.2 connection level. var ah stompngo.Headers if conn.Protocol() == stompngo.SPL_11 { // 1.1 ah = ah.Add("subscription", md.Message.Headers.Value("subscription")) ah = ah.Add("message-id", md.Message.Headers.Value("message-id")) } else { // 1.2 ah = ah.Add("id", md.Message.Headers.Value("ack")) } // We are also going to ask for a RECEIPT for the ACK rid := "receipt-001" ah = ah.Add("receipt", rid) // ll.Printf("%stag:%s connsess:%s ACK_receipt_headers headers:%v\n", exampid, tag, conn.Session(), ah) e = conn.Ack(ah) if e != nil { ll.Fatalf("%stag:%s connsess:%s ack_error error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } // **************************************** // Finally get the RECEIPT. Where is it? It is *not* on the "subscribe // channel". It is on the connection level MessageData channel. Why? // Because the broker does *not* include a "subscription" header in // RECEIPT frames.. // **************************************** // ***IMPORTANT*** // ***NOTE*** which channel this RECEIPT MessageData comes in on. ll.Printf("%stag:%s connsess:%s start_receipt_read\n", exampid, tag, conn.Session()) var rd stompngo.MessageData select { case rd = <-sc: // This would contain a MESSAGE frame. It is unexpected here // in this example. ll.Fatalf("%stag:%s connsess:%s bad_frame_channel rd:%v\n", exampid, tag, conn.Session(), rd) // Handle this ...... case rd = <-conn.MessageData: // RECEIPT frame s/b in the MessageData // Step 1 of Verify if rd.Message.Command != stompngo.RECEIPT { ll.Fatalf("%stag:%s connsess:%s bad_frame_command rd:%v\n", exampid, tag, conn.Session(), rd) // Handle this ...... } } ll.Printf("%stag:%s connsess:%s end_receipt_read\n", exampid, tag, conn.Session()) // **************************************** // Show details about the RECEIPT MessageData struct ll.Printf("%stag:%s connsess:%s receipt_COMMAND command:%s\n", exampid, tag, conn.Session(), rd.Message.Command) ll.Printf("%stag:%s connsess:%s receipt_HEADERS headers:%v\n", exampid, tag, conn.Session(), rd.Message.Headers) ll.Printf("%stag:%s connsess:%s receipt_BODY body:%s\n", exampid, tag, conn.Session(), string(rd.Message.Body)) // Step 2 of Verify // Verify that the receipt has the id we asked for if rd.Message.Headers.Value("receipt-id") != rid { ll.Fatalf("%stag:%s connsess:%s bad_receipt_id wanted:%v got:%v\n", exampid, tag, conn.Session(), rid, rd.Message.Headers.Value("receipt-id")) // Handle this ...... } ll.Printf("%stag:%s connsess:%s receipt_id_verified rid:%s\n", exampid, tag, conn.Session(), rid) // **************************************** // Disconnect from the Stomp server // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_disconnect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
func main() { st := time.Now() // **************************************** // Set up the connection. // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // **************************************** // App logic here ..... // Send exactly one message. Ask for a receipt. d := sngecomm.Dest() ll.Printf("%stag:%s connsess:%s destination:%v\n", exampid, tag, conn.Session(), d) rid := "recipt-002" // The receipt ID sh := stompngo.Headers{"destination", d, "receipt", rid} // send headers if senv.Persistent() { sh = sh.Add("persistent", "true") } ms := exampid + " message: " t := ms + rid ll.Printf("%stag:%s connsess:%s sending_now body:%v\n", exampid, tag, conn.Session(), t) e = conn.Send(sh, t) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_bad_send error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s send_complete body:%v\n", exampid, tag, conn.Session(), t) // Look for the receipt ll.Printf("%stag:%s connsess:%s start_receipt_read\n", exampid, tag, conn.Session()) rd := <-conn.MessageData // The RECEIPT frame should be on this channel if rd.Message.Command != stompngo.RECEIPT { ll.Fatalf("%stag:%s connsess:%s bad_frame_command rd:%v\n", exampid, tag, conn.Session(), rd) // Handle this ...... } ll.Printf("%stag:%s connsess:%s end_receipt_read\n", exampid, tag, conn.Session()) // **************************************** // Show details about the RECEIPT MessageData struct ll.Printf("%stag:%s connsess:%s receipt_COMMAND command:%s\n", exampid, tag, conn.Session(), rd.Message.Command) ll.Printf("%stag:%s connsess:%s receipt_HEADERS headers:%v\n", exampid, tag, conn.Session(), rd.Message.Headers) ll.Printf("%stag:%s connsess:%s receipt_BODY body:%s\n", exampid, tag, conn.Session(), string(rd.Message.Body)) // Step 2 of Verify // Verify that the receipt has the id we asked for if rd.Message.Headers.Value("receipt-id") != rid { ll.Fatalf("%stag:%s connsess:%s bad_receipt_id wanted:%v got:%v\n", exampid, tag, conn.Session(), rid, rd.Message.Headers.Value("receipt-id")) // Handle this ...... } ll.Printf("%stag:%s connsess:%s receipt_id_verified rid:%s\n", exampid, tag, conn.Session(), rid) e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_disconnect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker, subscribe and receive some messages and disconnect. func main() { st := time.Now() // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } session = conn.Session() conn.SetLogger(ll) // stompngo logging pbc := sngecomm.Pbc() // Print byte count d := senv.Dest() // Destination id := stompngo.Uuid() // A unique name/id nmsgs := senv.Nmsgs() // int number of messages to get mns := fmt.Sprintf("%d", nmsgs) // string number of messages to get am := sngecomm.AckMode() // ACK mode to use on SUBSCRIBE nfa := true // Need "final" ACK (possiby reset below) wh := stompngo.Headers{ // Starting SUBSCRIBE headers stompngo.StompPlusDrainAfter, mns} // Need a string here // Sanity check ACK mode if conn.Protocol() == stompngo.SPL_10 && am == stompngo.AckModeClientIndividual { ll.Fatalf("%stag:%s connsess:%s invalid_ack_mode am:%v proto:%v\n", exampid, tag, session, am, conn.Protocol()) // } // Do not do final ACK if running ACKs are issued if am == stompngo.AckModeClientIndividual || am == stompngo.AckModeAuto { nfa = false } // Show run parameters ll.Printf("%stag:%s connsess:%s run_parms\n\tpbc:%v\n\td:%v\n\tid:%v\n\tnmsgs:%v\n\tam:%v\n\tnfa:%v\n\twh:%v\n", exampid, tag, session, pbc, d, id, nmsgs, am, nfa, wh) // Run SUBSCRIBE sc := doSubscribe(conn, d, id, am, wh) ll.Printf("%stag:%s connsess:%s stomp_subscribe_complete\n", exampid, tag, session) var md stompngo.MessageData // Message data from basic read var lmd stompngo.MessageData // Possible save (copy) of received data mc := 1 // Initial message number // Loop for the requested number of messages GetLoop: for { ll.Printf("%stag:%s connsess:%s start_of_read_loop mc:%v nmsgs:%v\n", exampid, tag, session, mc, nmsgs) mcs := fmt.Sprintf("%d", mc) // string number message count // Get something from the stompngo read routine select { case md = <-sc: case md = <-conn.MessageData: // if md.Message.Command == stompngo.RECEIPT { ll.Printf("%stag:%s connsess:%s have_receipt md:%v\n", exampid, tag, session, md) continue GetLoop } ll.Fatalf("%stag:%s connsess:%s ERROR_frame hdrs:%v body:%v\n", exampid, tag, session, md.Message.Headers, string(md.Message.Body)) // Handle this ...... } // Save message data for possible use in the final ACK if mc == nmsgs && nfa { lmd = md // Save last message } // Basic loop logging ll.Printf("%stag:%s connsess:%s channel_read_complete mns:%s mc:%d\n", exampid, tag, session, mns, mc) ll.Printf("%stag:%s connsess:%s message_number:%v\n", exampid, tag, session, mc) // Check if reader returned any error if md.Error != nil { ll.Fatalf("%stag:%s connsess:%s error_read error:%v", exampid, tag, session, md.Error) // Handle this ...... } // Show frame type ll.Printf("%stag:%s connsess:%s frame_type cmd:%s\n", exampid, tag, session, md.Message.Command) // Pure sanity check: this should *never* happen based on logic // above. if md.Message.Command != stompngo.MESSAGE { ll.Fatalf("%stag:%s connsess:%s error_frame_type md:%v", exampid, tag, session, md) // Handle this ...... } // Show Message Headers wh := md.Message.Headers for j := 0; j < len(wh)-1; j += 2 { ll.Printf("%stag:%s connsess:%s Header:%s:%s\n", exampid, tag, session, wh[j], wh[j+1]) } // Show (part of) Message Body if pbc > 0 { maxlen := pbc if len(md.Message.Body) < maxlen { maxlen = len(md.Message.Body) } ss := string(md.Message.Body[0:maxlen]) ll.Printf("%stag:%s connsess:%s payload body:%s\n", exampid, tag, session, ss) } // Sanity check this message payload wm := wlp + mcs // The left part plus the (string) meassage number] bm := string(md.Message.Body) if bm != wm { ll.Fatalf("%stag:%s connsess:%s error_message_payload\n\tGot %s\n\tWant%s\n", exampid, tag, session, bm, wm) // Handle this ...... } else { ll.Printf("%stag:%s connsess:%s matched_body_string\n%s\n%s\n", exampid, tag, session, bm, wm) // Handle this ......) } // Run individual ACK if required if am == stompngo.AckModeClientIndividual { wh := md.Message.Headers // Copy Headers if ar { // ACK receipt wanted wh = wh.Add(stompngo.HK_RECEIPT, "rwanted-"+mcs) } sngecomm.HandleAck(conn, wh, id) ll.Printf("%stag:%s connsess:%s individual_ack_complete mc:%v headers:%v\n", exampid, tag, session, mc, md.Message.Headers) } // Check for end of loop condition if mc == nmsgs { break } // Increment loop/message counter mc++ } // Issue the final ACK if needed if nfa { wh := lmd.Message.Headers // Copy Headers if ar { // ACK receipt wanted wh = wh.Add(stompngo.HK_RECEIPT, "rwanted-fin") } sngecomm.HandleAck(conn, wh, id) ll.Printf("%stag:%s connsess:%s final_ack_complete\n", exampid, tag, session) if ar { getReceipt(conn) } } // Unsubscribe (may be skipped if requested) if unsub { sngecomm.HandleUnsubscribe(conn, d, id) ll.Printf("%stag:%s connsess:%s stomp_unsubscribe_complete\n", exampid, tag, session) } else { ll.Printf("%stag:%s connsess:%s skipping_unsubscribe\n", exampid, tag, session) } // Standard example disconnect sequence (may be skipped if requested) // a) Closes the *stompngo.Connection // b) Closes the net.Conn if dodisc { e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, session, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s disconnect_receipt:%v\n", exampid, tag, session, conn.DisconnectReceipt) } else { ll.Printf("%stag:%s connsess:%s skipping_disconnect\n", exampid, tag, session) } // End of work logging, show elapsed time ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, session, time.Now().Sub(st)) }
// Connect to a STOMP broker, receive some messages, ACK them, and disconnect. func main() { st := time.Now() // Standard example connect sequence n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } pbc := sngecomm.Pbc() // Print byte count // *NOTE* your application functionaltiy goes here! // With Stomp, you must SUBSCRIBE to a destination in order to receive. // Subscribe returns a channel of MessageData struct. // Here we use a common utility routine to handle the differing subscribe // requirements of each protocol level. d := senv.Dest() id := stompngo.Uuid() sc := sngecomm.HandleSubscribe(conn, d, id, "client") ll.Printf("%stag:%s connsess:%s main_subscribe_complete\n", exampid, tag, conn.Session()) // Read data from the returned channel var md stompngo.MessageData for i := 1; i <= senv.Nmsgs(); i++ { select { case md = <-sc: case md = <-conn.MessageData: // Frames RECEIPT or ERROR not expected here ll.Fatalf("%stag:%s connsess:%s main_channel_frame error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_channel_read_complete\n", exampid, tag, conn.Session()) // MessageData has two components: // a) a Message struct // b) an Error value. Check the error value as usual if md.Error != nil { ll.Fatalf("%stag:%s connsess:%s main_channel_read error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } // ll.Printf("%stag:%s connsess:%s frame_type:%v\n", exampid, tag, conn.Session(), md.Message.Command) if md.Message.Command != stompngo.MESSAGE { ll.Fatalf("%stag:%s connsess:%s bad_frame frame:%v", exampid, tag, conn.Session(), md.Message.Command) // Handle this ...... } wh := md.Message.Headers for j := 0; j < len(wh)-1; j += 2 { ll.Printf("%stag:%s connsess:%s header:%s:%s\n", exampid, tag, conn.Session(), wh[j], wh[j+1]) } if pbc > 0 { maxlen := pbc if len(md.Message.Body) < maxlen { maxlen = len(md.Message.Body) } ss := string(md.Message.Body[0:maxlen]) ll.Printf("%stag:%s connsess:%s message_payload body:%s\n", exampid, tag, conn.Session(), ss) } // ACK the message just received. // Agiain we use a utility routine to handle the different requirements // of the protocol versions. sngecomm.HandleAck(conn, md.Message.Headers, id) ll.Printf("%stag:%s connsess:%s ack_complete\n", exampid, tag, conn.Session()) } // It is polite to unsubscribe, although unnecessary if a disconnect follows. // Again we use a utility routine to handle the different protocol level // requirements. sngecomm.HandleUnsubscribe(conn, d, id) ll.Printf("%stag:%s connsess:%s stomp_unsubscribe_complete\n", exampid, tag, conn.Session()) // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker using TLS and disconnect. func main() { st := time.Now() ll.Printf("%stag:%s connsess:%s starts\n", exampid, tag, sngecomm.Lcs) flag.Parse() // Parse flags ll.Printf("%stag:%s connsess:%s main_using_srvCAFile:%s\n", exampid, tag, sngecomm.Lcs, srvCAFile) // TLS Configuration. tc = new(tls.Config) tc.InsecureSkipVerify = false // *Do* check the broker's certificate // Be polite, allow SNI (Server Virtual Hosting) tc.ServerName = senv.Host() // Usually one will use the default cipher suites that go provides. // However, if a custom cipher squite list is needed/required this // is how it is accomplished. if sngecomm.UseCustomCiphers() { // Set custom cipher suite list tc.CipherSuites = append(tc.CipherSuites, sngecomm.CustomCiphers()...) } // Finish TLS Config initialization, so client can authenticate broker. b, e := ioutil.ReadFile(srvCAFile) // Read broker's CA cert (PEM) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_read_file error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } k, _ := pem.Decode(b) // Decode PEM format (*pem.Block) if k == nil { ll.Fatalf("%stag:%s connsess:%s main_decode error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } c, e := x509.ParseCertificate(k.Bytes) // Create *x509.Certificate if e != nil { ll.Fatalf("%stag:%s connsess:%s main_parse_cert error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } tc.RootCAs = x509.NewCertPool() // Create a cert "pool" tc.RootCAs.AddCert(c) // Add the CA cert to the pool // Standard example TLS connect sequence n, conn, e := sngecomm.CommonTLSConnect(exampid, tag, ll, tc) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } nc := n.(*tls.Conn) sngecomm.DumpTLSConfig(exampid, tc, nc) // *NOTE* application specific functionaltiy starts here! // For you to add. // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker, receive some messages and disconnect. func main() { st := time.Now() // Standard example connect sequence // Use AMQ port here n, conn, e := sngecomm.CommonConnect(exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } pbc := sngecomm.Pbc() // Print byte count // Setup Headers ... id := stompngo.Uuid() // Use package convenience function for unique ID d := "jms.queue.exampleQueue" sc := sngecomm.HandleSubscribe(conn, d, id, "auto") ll.Printf("%stag:%s connsess:%s stomp_subscribe_complete\n", exampid, tag, conn.Session()) // var md stompngo.MessageData // Read data from the returned channel for i := 1; i <= nmsgs; i++ { select { case md = <-sc: case md = <-conn.MessageData: // Frames RECEIPT or ERROR not expected here ll.Fatalf("%stag:%s connsess:%s bad_frame error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s channel_read_complete\n", exampid, tag, conn.Session()) // MessageData has two components: // a) a Message struct // b) an Error value. Check the error value as usual if md.Error != nil { ll.Fatalf("%stag:%s connsess:%s error_read error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s frame_type cmd:%s\n", exampid, tag, conn.Session(), md.Message.Command) if md.Message.Command != stompngo.MESSAGE { ll.Fatalf("%stag:%s connsess:%s error_frame_type error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } wh := md.Message.Headers for j := 0; j < len(wh)-1; j += 2 { ll.Printf("%stag:%s connsess:%s Header:%s:%s\n", exampid, tag, conn.Session(), wh[j], wh[j+1]) } if pbc > 0 { maxlen := pbc if len(md.Message.Body) < maxlen { maxlen = len(md.Message.Body) } ss := string(md.Message.Body[0:maxlen]) ll.Printf("%stag:%s connsess:%s payload body:%s\n", exampid, tag, conn.Session(), ss) } } // sngecomm.HandleUnsubscribe(conn, d, id) ll.Printf("%stag:%s connsess:%s unsubscribe_complete\n", exampid, tag, conn.Session()) // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// A forever reader. func main() { st := time.Now() sngecomm.ShowRunParms(exampid) // Standard example connect sequence var e error n, conn, e = sngecomm.CommonConnect(exampid, tag, ll) if e != nil { if conn != nil { ll.Printf("%stag:%s connsess:%s Connect Response headers:%v body%s\n", exampid, tag, conn.Session(), conn.ConnectResponse.Headers, string(conn.ConnectResponse.Body)) } ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } //** qn := 1 ltag := tag + "-receiver" id := stompngo.Uuid() // A unique subscription ID d := sngecomm.Dest() ll.Printf("%stag:%s connsess:%s queue_info id:%v d:%v qnum:%v\n", exampid, ltag, conn.Session(), id, d, qn) // Subscribe sc := sngecomm.HandleSubscribe(conn, d, id, sngecomm.AckMode()) ll.Printf("%stag:%s connsess:%s subscribe_complete id:%v d:%v qnum:%v\n", exampid, ltag, conn.Session(), id, d, qn) // var md stompngo.MessageData // Receive loop mc := 1 for { ll.Println("========================== ", "Expecting Message:", mc, "==========================") select { case md = <-sc: case md = <-conn.MessageData: // A RECEIPT or ERROR frame is unexpected here ll.Fatalf("%stag:%s connsess:%s bad_frame qnum:%v headers:%v body:%s", exampid, tag, conn.Session(), qn, md.Message.Headers, md.Message.Body) // Handle this ...... } if md.Error != nil { ll.Fatalf("%stag:%s connsess:%s recv_error qnum:%v error:%v", exampid, tag, conn.Session(), qn, md.Error) // Handle this ...... } ll.Printf("%stag:%s connsess:%s next_frame mc:%v command:%v headers:%v body:%v\n", exampid, tag, conn.Session(), mc, md.Message.Command, md.Message.Headers, string(md.Message.Body)) // Handle this ...... mc++ } //** // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } sngecomm.ShowStats(exampid, tag, conn) ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Connect to a STOMP broker using TLS and disconnect. func main() { st := time.Now() ll.Printf("%stag:%s connsess:%s starts\n", exampid, tag, sngecomm.Lcs) flag.Parse() // Parse flags ll.Printf("%stag:%s connsess:%s main_using_cliCertFile:%s\n", exampid, tag, sngecomm.Lcs, cliCertFile) ll.Printf("%stag:%s connsess:%s main_using_cliKeyFile:%s\n", exampid, tag, sngecomm.Lcs, cliKeyFile) // TLS Configuration. tc = new(tls.Config) tc.InsecureSkipVerify = true // Do *not* check the broker's certificate // Be polite, allow SNI (Server Virtual Hosting) tc.ServerName = senv.Host() // Usually one will use the default cipher suites that go provides. // However, if a custom cipher squite list is needed/required this // is how it is accomplished. if sngecomm.UseCustomCiphers() { // Set custom cipher suite list tc.CipherSuites = append(tc.CipherSuites, sngecomm.CustomCiphers()...) } // Finish TLS Config initialization, so broker can authenticate client. // cc -> tls.Certificate cc, e := tls.LoadX509KeyPair(cliCertFile, cliKeyFile) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_load_pair error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // Add cert to config tc.Certificates = append(tc.Certificates, cc) // This is OK, but does not seem to be required tc.BuildNameToCertificate() // Build names map // Standard example TLS connect sequence n, conn, e := sngecomm.CommonTLSConnect(exampid, tag, ll, tc) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } nc := n.(*tls.Conn) sngecomm.DumpTLSConfig(exampid, tc, nc) // *NOTE* application specific functionaltiy starts here! // For you to add. // *NOTE* application specific functionaltiy ends here! // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ...... } ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }
// Show a number of writers and readers operating concurrently from unique // destinations. func main() { st := time.Now() sngecomm.ShowRunParms(exampid) ll.Printf("%stag:%s connsess:%s main_starts\n", exampid, tag, sngecomm.Lcs) ll.Printf("%stag:%s connsess:%s main_profiling pprof:%v\n", exampid, tag, sngecomm.Lcs, sngecomm.Pprof()) ll.Printf("%stag:%s connsess:%s main_current_GOMAXPROCS gmp:%v\n", exampid, tag, sngecomm.Lcs, runtime.GOMAXPROCS(-1)) if sngecomm.SetMAXPROCS() { nc := runtime.NumCPU() ll.Printf("%stag:%s connsess:%s main_current_num_cpus cncpu:%v\n", exampid, tag, sngecomm.Lcs, nc) gmp := runtime.GOMAXPROCS(nc) ll.Printf("%stag:%s connsess:%s main_previous_num_cpus pncpu:%v\n", exampid, tag, sngecomm.Lcs, gmp) ll.Printf("%stag:%s connsess:%s main_current_GOMAXPROCS gmp:%v\n", exampid, tag, sngecomm.Lcs, runtime.GOMAXPROCS(-1)) } // Wait flags sw = sngecomm.SendWait() rw = sngecomm.RecvWait() sf = sngecomm.SendFactor() rf = sngecomm.RecvFactor() ll.Printf("%stag:%s connsess:%s main_wait_sleep_factors sw:%v rw:%v sf:%v rf:%v\n", exampid, tag, sngecomm.Lcs, sw, rw, sf, rf) // Number of queues nqs := sngecomm.Nqs() // Standard example connect sequence var e error n, conn, e = sngecomm.CommonConnect(exampid, tag, ll) if e != nil { if conn != nil { ll.Printf("%stag:%s connsess:%s Connect Response headers:%v body%s\n", exampid, tag, conn.Session(), conn.ConnectResponse.Headers, string(conn.ConnectResponse.Body)) } ll.Fatalf("%stag:%s connsess:%s main_on_connect error:%v", exampid, tag, sngecomm.Lcs, e.Error()) // Handle this ...... } // Many receivers running under the same connection can cause // (wire read) performance issues. This is *very* dependent on the broker // being used, specifically the broker's algorithm for putting messages on // the wire. // To alleviate those issues, this strategy insures that messages are // received from the wire as soon as possible. Those messages are then // buffered internally for (possibly later) application processing. In // this example, buffering occurs in the stompngo package. conn.SetSubChanCap(senv.SubChanCap()) // Experiment with this value, YMMV // Run everything wga.Add(2) go startReceivers(nqs) go startSenders(nqs) wga.Wait() // Standard example disconnect sequence e = sngecomm.CommonDisconnect(n, conn, exampid, tag, ll) if e != nil { ll.Fatalf("%stag:%s connsess:%s main_on_disconnect error:%v", exampid, tag, conn.Session(), e.Error()) // Handle this ...... } sngecomm.ShowStats(exampid, tag, conn) ll.Printf("%stag:%s connsess:%s main_elapsed:%v\n", exampid, tag, conn.Session(), time.Now().Sub(st)) }