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
}
示例#4
0
// 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))
}
示例#5
0
// 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))

}
示例#6
0
// 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))
}
示例#7
0
// 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))

}
示例#9
0
// 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))

}
示例#10
0
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()
}
示例#11
0
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))

}
示例#12
0
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))

}
示例#13
0
// 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))
}
示例#14
0
// 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))

}
示例#15
0
// 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))

}
示例#16
0
// 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))

}
示例#17
0
// 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))

}
示例#18
0
// 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))

}
示例#19
0
// 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))

}