A STOMP Client package for go developers, supporting all STOMP specification levels.

Related tags

Network stompngo
Overview

stompngo - A STOMP 1.0, 1.1 and 1.2 Client Package

Features

References

Installation

Installation requires a working go environment. For current versions of go issue:

  • go get github.com/gmallard/stompngo

The GOPATH environment variable must be set properly.

It is also possible to just clone the stompngo repository to any location of choice, and use go modules to locate it.

Examples

The examples in the included unit tests can be used as a good starting point.

Also see the examples project:

QA

The tests for this STOMP client package run against recent releases of:

See the tests for relevant environment variables.

NOTE: For testing with rabbitmq, you also need export STOMP_RMQ="/" due to the default vhost of rabbitmq is "/" instead of "localhost".

Contributions

Any and all are welcome by pull request or e-mail patch.

Wiki

News and notes will be posted from time to time at the stompngo wiki:

Please review and update that on occaision.

Canonical Repository

For the record, the canonical repository for this project is at:

Issues

Please review issues at the canonical repository. File any new issues there as well:

Contributors List

See CONTRIBUTORS.md.

Comments
  • adding locking and closed-checking to make sure that we do not write to ...

    adding locking and closed-checking to make sure that we do not write to ...

    ...closed channels

    Thank you for all your work on this stompngo library, we've been putting it through its paces. In the course of doing that, we've discovered that sometimes when we Disconnect() a stompngo Connection object, we get a panic, as it has a goroutine trying to write to the c.input channel that's just been closed in the Disconnect() method.

    I believe this patch should address that race condition.

    opened by danieltmiles 26
  • Disconnect hangs

    Disconnect hangs

    Hello, Thanks a lot for developing this nice tool. I've got a question regarding the connection Disconnect function; when I use it, it hangs, and when I debug it, the debugger stops at the following line: https://github.com/gmallard/stompngo/blob/78e25a2785946491585cc90d1d9a5ca9266eaee4/disconnect.go#L83 Do you have any ideas why this might be the case? Thanks a lot for your help in advance. Feel free to let me know if you need any further information.

    opened by c-bg 23
  • shutdownHeartbeats is not shutting down heartbeats

    shutdownHeartbeats is not shutting down heartbeats

    Hello,

    I came across this debugging an app I'm working on. I can see that the app is gettng an error (EOF), which is causing the reader and writer to shut down. However, the system is still trying to send heartbeats afterwards. Unfortunately, I tried to trace through this a bit to no avail. The issue with this is that it looks like the client doesn't die and continues to send heartbeats. My preference would be that if the connection dies, the client sends back an error.

    I'll keep a copy of this log file handy in case you need more info. Unfortunately, I can't share it.

    opened by sybrandy 16
  • Support timeouts for network reads/writes

    Support timeouts for network reads/writes

    Hello,

    We ran across an issue with RabbitMQ and stompngo where if we spammed RabbitMQ fast enough, we would get Heartbeat errors. While debugging this, it appears that it got into a state where the connection crapped out and it the bufio writer would not write the data. Put a timeout deadline on network connection before sending data helped a bit, but it still locked up.

    Regardless of what happens, it may be a good idea to allow the user to specify a timeout for read/write operations. This way, if there any network issues, they aren't silently ignored in the worst case.

    opened by sybrandy 16
  • stompngo should not panic when parsing headers, return an error instead.

    stompngo should not panic when parsing headers, return an error instead.

    While connecting to an Apache Apollo broker I ran into the following:

    panic: runtime error: index out of range
    
    goroutine 7 [running]:
    runtime.panic(0x6292c0, 0x8e4837)
        /usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
    github.com/gmallard/stompngo.(*Connection).readFrame(0xc210072000, 0xc21000aa60, 0xe, 0x8f2490, 0x0, ...)
        /Users/kelseyhightower/go/src/github.com/gmallard/stompngo/reader.go:122 +0x85e
    github.com/gmallard/stompngo.(*Connection).reader(0xc210072000)
        /Users/kelseyhightower/go/src/github.com/gmallard/stompngo/reader.go:36 +0x3a
    created by github.com/gmallard/stompngo.Connect
        /Users/kelseyhightower/go/src/github.com/gmallard/stompngo/connect.go:111 +0x7c9
    

    The root cause seems to be reading an invalid header during the readFrame() method:

    s = s[0 : len(s)-1]
    p := strings.SplitN(s, ":", 2)
    if c.Protocol() != SPL_10 && f.Command != CONNECTED {
      p[0] = decode(p[0])
      p[1] = decode(p[1])
    }
    

    which leads to

    panic: runtime error: index out of range
    

    I'm thinking we need to do some bounds checking here, and return a custom error message regrading the invalid headers. I'm happy to work on this if you think this is the right direction to go.

    Closed 
    opened by kelseyhightower 12
  • Go get fetching the go1 branch

    Go get fetching the go1 branch

    Hi, by default github and godoc are displaying the master branch as default, but when calling go get github.com/gmallard/stompngo a go1 branch is downloaded.

    Which branch should I use? Master seems more reasonable, the missing constants in the go1 branch like HK_DESTINATION are annoying.

    opened by szank 9
  • panic running tests on go1.3.1 linux/amd64

    panic running tests on go1.3.1 linux/amd64

    [email protected]:~/go/src/github.com/danieltmiles/stompngo$ go version go version go1.3.1 linux/amd64 [email protected]:~/go/src/github.com/danieltmiles/stompngo$ env | grep GO GOPATH=/home/dmiles/go [email protected]:~/go/src/github.com/danieltmiles/stompngo$ go build [email protected]:~/go/src/github.com/danieltmiles/stompngo$ echo $? 0 [email protected]:~/go/src/github.com/danieltmiles/stompngo$ go test -v === RUN TestAckErrors === RUN TestAckSameConn === RUN TestAckDiffConn === RUN TestCodecEncodeBasic === RUN TestCodecDecodeBasic === RUN TestCodec11SendRecvCodec --- SKIP: TestCodec11SendRecvCodec (0.00 seconds) codec_test.go:100: Test11SendRecvCodec norun === RUN TestConnBadVer10One --- SKIP: TestConnBadVer10One (0.00 seconds) connbv_test.go:30: TestConnBadVer10One no 1.0 only servers available === RUN TestConnBadVer10Two --- SKIP: TestConnBadVer10Two (0.00 seconds) connbv_test.go:50: TestConnBadVer10Two norun, set STOMP_TESTBV === RUN TestConnBadVer10Three --- SKIP: TestConnBadVer10Three (0.00 seconds) connbv_test.go:76: TestConnBadVer10Three norun, set STOMP_TESTBV === RUN TestConnDiscNetconn === RUN TestConnDiscStompConn === RUN TestConnDiscStompDisc === RUN TestConnDiscStompDiscReceipt === RUN TestConnBodyLen === RUN TestConn11p === RUN TestConn11Receipt === RUN TestEconBad === RUN TestSetProtocolLevel === RUN TestConnRespData === RUN TestDataFrameBasic === RUN TestDataMessageBasic === RUN TestDataprotocols === RUN TestDataProtocols === RUN TestDataError === RUN TestDataMessageSize === RUN TestBrokerCmdVal === RUN TestHB10 === RUN TestHB11NoHeader === RUN TestHB11ZeroHeader === RUN TestHB11InitErrors === RUN TestHB11Connect --- SKIP: TestHB11Connect (0.00 seconds) hb_test.go:160: TestHB11Connect norun, need 1.1+ === RUN TestHB11NoSend --- SKIP: TestHB11NoSend (0.00 seconds) hb_test.go:192: TestHB11NoSend norun, need 1.1+ === RUN TestHB11NoReceive --- SKIP: TestHB11NoReceive (0.00 seconds) hb_test.go:236: TestHB11NoReceive norun, need 1.1+ === RUN TestHB11SendReceive --- SKIP: TestHB11SendReceive (0.00 seconds) hb_test.go:276: TestHB11SendReceive norun, need 1.1+ === RUN TestHB11SendReceiveApollo --- SKIP: TestHB11SendReceiveApollo (0.00 seconds) hb_test.go:323: TestHB11SendReceiveApollo norun, need 1.1+ === RUN TestHB11SendReceiveApolloRev --- SKIP: TestHB11SendReceiveApolloRev (0.00 seconds) hb_test.go:371: TestHB11SendReceiveApolloRev norun, need 1.1+ === RUN TestDataHeadersBasic === RUN TestDataHeadersUTF8 === RUN TestDataHeadersClone === RUN TestDataHeadersAddDelete === RUN TestDataHeadersContainsKV === RUN TestDataHeadersCompare === RUN TestDataHeadersSize === RUN TestDataHeadersEmtKV === RUN TestLoggerBasic === RUN TestBytes0 === RUN TestBytes1 === RUN TestNilHeaders === RUN TestMax === RUN TestHasValue === RUN TestUuid === RUN TestBadHeaders === RUN TestNackErrors === RUN TestSendBasic === RUN TestSendMultiple === RUN TestSendBytesBasic === RUN TestSendBytesMultiple === RUN TestSubNoSub === RUN TestSubNoIdOnce === RUN TestSubNoIdTwice10 === RUN TestSubNoIdTwice11p --- SKIP: TestSubNoIdTwice11p (0.00 seconds) sub_test.go:164: TestSubNoIdTwice11p norun, need 1.1+ === RUN TestSubUnsubBasic === RUN TestSubUnsubBasic10 === RUN TestSubEstablishSubscription === RUN TestSubSetCap --- SKIP: TestSubSetCap (0.00 seconds) sub_test.go:335: TestSubSetCap norun, need 1.1+ === RUN TestTransErrors === RUN TestTransSend === RUN TestTransSendRollback === RUN TestTransMessageOrder === RUN TestUnsubNoHdr === RUN TestUnsubNoId === RUN TestUnsubBadId === RUN TestShovel11 --- SKIP: TestShovel11 (0.00 seconds) wrsubrduns_test.go:29: Test11Shovel norun, need 1.1+ panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x20 pc=0x4edf0c]

    goroutine 153 [running]: runtime.panic(0x5e9760, 0x730e13) /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5 bufio.(_Writer).flush(0xc208042c00, 0x0, 0x0) /usr/local/go/src/pkg/bufio/bufio.go:530 +0xdc bufio.(_Writer).Flush(0xc208042c00, 0x0, 0x0) /usr/local/go/src/pkg/bufio/bufio.go:519 +0x39 github.com/danieltmiles/stompngo.(_Connection).wireWrite(0xc208054100, 0x60c090, 0x7, 0xc208042b80, 0x4, 0x4, 0x735b30, 0x0, 0x0, 0xc20807c000) /home/dmiles/go/src/github.com/danieltmiles/stompngo/writer.go:64 +0x38e github.com/danieltmiles/stompngo.(_Connection).writer(0xc208054100) /home/dmiles/go/src/github.com/danieltmiles/stompngo/writer.go:35 +0xcb created by github.com/danieltmiles/stompngo.Connect /home/dmiles/go/src/github.com/danieltmiles/stompngo/connect.go:93 +0x656

    goroutine 16 [chan receive]: testing.RunTests(0x675460, 0x733520, 0x49, 0x49, 0x1) /usr/local/go/src/pkg/testing/testing.go:525 +0x519 testing.Main(0x675460, 0x733520, 0x49, 0x49, 0x72f160, 0x4, 0x4, 0x7399c0, 0x0, 0x0) /usr/local/go/src/pkg/testing/testing.go:435 +0x84 main.main() github.com/danieltmiles/stompngo/_test/_testmain.go:199 +0x9c

    goroutine 19 [finalizer wait]: runtime.park(0x4137f0, 0x7356c0, 0x734229) /usr/local/go/src/pkg/runtime/proc.c:1369 +0x89 runtime.parkunlock(0x7356c0, 0x734229) /usr/local/go/src/pkg/runtime/proc.c:1385 +0x3b runfinq() /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xcf runtime.goexit() /usr/local/go/src/pkg/runtime/proc.c:1445

    goroutine 20 [runnable]: github.com/danieltmiles/stompngo.Connect(0x0, 0x0, 0x72ed80, 0x4, 0x4, 0x4, 0x0, 0x0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/connect.go:96 +0x75c github.com/danieltmiles/stompngo.TestAckErrors(0xc208050120) /home/dmiles/go/src/github.com/danieltmiles/stompngo/ack_test.go:72 +0xdf testing.tRunner(0xc208050120, 0x733520) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 21 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 22 [chan receive]: testing.(*T).Parallel(0xc2080501b0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestAckSameConn(0xc2080501b0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/ack_test.go:98 +0x35 testing.tRunner(0xc2080501b0, 0x733538) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 23 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 24 [chan receive]: testing.(*T).Parallel(0xc208050240) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestAckDiffConn(0xc208050240) /home/dmiles/go/src/github.com/danieltmiles/stompngo/ack_test.go:179 +0x35 testing.tRunner(0xc208050240, 0x733550) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 25 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 26 [chan receive]: testing.(*T).Parallel(0xc2080502d0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestCodecEncodeBasic(0xc2080502d0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/codec_test.go:52 +0x35 testing.tRunner(0xc2080502d0, 0x733568) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 27 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 28 [chan receive]: testing.(*T).Parallel(0xc208050360) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestCodecDecodeBasic(0xc208050360) /home/dmiles/go/src/github.com/danieltmiles/stompngo/codec_test.go:68 +0x35 testing.tRunner(0xc208050360, 0x733580) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 29 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 34 [chan receive]: testing.(*T).Parallel(0xc208050630) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnDiscNetconn(0xc208050630) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:43 +0x27 testing.tRunner(0xc208050630, 0x7335f8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 35 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 36 [chan receive]: testing.(*T).Parallel(0xc2080506c0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnDiscStompConn(0xc2080506c0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:52 +0x35 testing.tRunner(0xc2080506c0, 0x733610) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 37 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 38 [chan receive]: testing.(*T).Parallel(0xc208050750) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnDiscStompDisc(0xc208050750) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:117 +0x32 testing.tRunner(0xc208050750, 0x733628) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 39 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 40 [chan receive]: testing.(*T).Parallel(0xc2080507e0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnDiscStompDiscReceipt(0xc2080507e0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:132 +0x35 testing.tRunner(0xc2080507e0, 0x733640) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 41 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 42 [chan receive]: testing.(*T).Parallel(0xc208050870) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnBodyLen(0xc208050870) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:160 +0x32 testing.tRunner(0xc208050870, 0x733658) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 43 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 44 [chan receive]: testing.(*T).Parallel(0xc208050000) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConn11p(0xc208050000) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:179 +0x35 testing.tRunner(0xc208050000, 0x733670) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 45 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 46 [chan receive]: testing.(*T).Parallel(0xc2080503f0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConn11Receipt(0xc2080503f0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:211 +0x35 testing.tRunner(0xc2080503f0, 0x733688) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 47 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 48 [chan receive]: testing.(*T).Parallel(0xc208050480) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestEconBad(0xc208050480) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:229 +0x32 testing.tRunner(0xc208050480, 0x7336a0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 49 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 50 [chan receive]: testing.(*T).Parallel(0xc208050510) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSetProtocolLevel(0xc208050510) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:278 +0x35 testing.tRunner(0xc208050510, 0x7336b8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 51 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 52 [chan receive]: testing.(*T).Parallel(0xc208050900) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestConnRespData(0xc208050900) /home/dmiles/go/src/github.com/danieltmiles/stompngo/conndisc_test.go:300 +0x35 testing.tRunner(0xc208050900, 0x7336d0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 53 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 54 [chan receive]: testing.(*T).Parallel(0xc208050990) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataFrameBasic(0xc208050990) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:41 +0x35 testing.tRunner(0xc208050990, 0x7336e8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 55 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 56 [chan receive]: testing.(*T).Parallel(0xc208050a20) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataMessageBasic(0xc208050a20) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:62 +0x35 testing.tRunner(0xc208050a20, 0x733700) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 57 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 58 [chan receive]: testing.(*T).Parallel(0xc208050ab0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataprotocols(0xc208050ab0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:83 +0x35 testing.tRunner(0xc208050ab0, 0x733718) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 59 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 60 [chan receive]: testing.(*T).Parallel(0xc208050b40) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataProtocols(0xc208050b40) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:113 +0x35 testing.tRunner(0xc208050b40, 0x733730) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 61 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 62 [chan receive]: testing.(*T).Parallel(0xc208050bd0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataError(0xc208050bd0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:126 +0x32 testing.tRunner(0xc208050bd0, 0x733748) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 63 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 64 [chan receive]: testing.(*T).Parallel(0xc208050c60) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataMessageSize(0xc208050c60) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:138 +0x35 testing.tRunner(0xc208050c60, 0x733760) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 65 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 66 [chan receive]: testing.(*T).Parallel(0xc208050cf0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestBrokerCmdVal(0xc208050cf0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/data_test.go:156 +0x35 testing.tRunner(0xc208050cf0, 0x733778) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 67 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 68 [chan receive]: testing.(*T).Parallel(0xc208050d80) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestHB10(0xc208050d80) /home/dmiles/go/src/github.com/danieltmiles/stompngo/hb_test.go:31 +0x27 testing.tRunner(0xc208050d80, 0x733790) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 69 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 70 [chan receive]: testing.(*T).Parallel(0xc208050e10) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestHB11NoHeader(0xc208050e10) /home/dmiles/go/src/github.com/danieltmiles/stompngo/hb_test.go:47 +0x32 testing.tRunner(0xc208050e10, 0x7337a8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 71 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 72 [chan receive]: testing.(*T).Parallel(0xc208050ea0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestHB11ZeroHeader(0xc208050ea0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/hb_test.go:68 +0x35 testing.tRunner(0xc208050ea0, 0x7337c0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 73 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 74 [chan receive]: testing.(*T).Parallel(0xc208050f30) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestHB11InitErrors(0xc208050f30) /home/dmiles/go/src/github.com/danieltmiles/stompngo/hb_test.go:89 +0x35 testing.tRunner(0xc208050f30, 0x7337d8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 75 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 82 [chan receive]: testing.(*T).Parallel(0xc208051320) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersBasic(0xc208051320) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:27 +0x35 testing.tRunner(0xc208051320, 0x733880) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 83 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 84 [chan receive]: testing.(*T).Parallel(0xc2080513b0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersUTF8(0xc2080513b0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:59 +0x35 testing.tRunner(0xc2080513b0, 0x733898) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 85 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 86 [chan receive]: testing.(*T).Parallel(0xc208051440) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersClone(0xc208051440) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:93 +0x35 testing.tRunner(0xc208051440, 0x7338b0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 87 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 88 [chan receive]: testing.(*T).Parallel(0xc2080514d0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersAddDelete(0xc2080514d0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:105 +0x35 testing.tRunner(0xc2080514d0, 0x7338c8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 89 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 90 [chan receive]: testing.(*T).Parallel(0xc208051560) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersContainsKV(0xc208051560) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:127 +0x32 testing.tRunner(0xc208051560, 0x7338e0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 91 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 92 [chan receive]: testing.(*T).Parallel(0xc2080515f0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersCompare(0xc2080515f0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:143 +0x35 testing.tRunner(0xc2080515f0, 0x7338f8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 93 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 94 [chan receive]: testing.(*T).Parallel(0xc208051680) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersSize(0xc208051680) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:170 +0x35 testing.tRunner(0xc208051680, 0x733910) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 95 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 96 [chan receive]: testing.(*T).Parallel(0xc208051710) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestDataHeadersEmtKV(0xc208051710) /home/dmiles/go/src/github.com/danieltmiles/stompngo/headers_test.go:190 +0x35 testing.tRunner(0xc208051710, 0x733928) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 97 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 98 [chan receive]: testing.(*T).Parallel(0xc2080517a0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestLoggerBasic(0xc2080517a0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/logger_test.go:29 +0x32 testing.tRunner(0xc2080517a0, 0x733940) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 99 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 100 [chan receive]: testing.(*T).Parallel(0xc208051830) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestBytes0(0xc208051830) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:27 +0x35 testing.tRunner(0xc208051830, 0x733958) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 101 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 102 [chan receive]: testing.(*T).Parallel(0xc2080518c0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestBytes1(0xc2080518c0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:79 +0x35 testing.tRunner(0xc2080518c0, 0x733970) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 103 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 104 [chan receive]: testing.(*T).Parallel(0xc208051950) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestNilHeaders(0xc208051950) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:131 +0x35 testing.tRunner(0xc208051950, 0x733988) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 105 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 106 [chan receive]: testing.(*T).Parallel(0xc2080519e0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestMax(0xc2080519e0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:197 +0x32 testing.tRunner(0xc2080519e0, 0x7339a0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 107 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 108 [chan receive]: testing.(*T).Parallel(0xc208051a70) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestHasValue(0xc208051a70) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:214 +0x32 testing.tRunner(0xc208051a70, 0x7339b8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 109 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 110 [chan receive]: testing.(*T).Parallel(0xc208051b00) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestUuid(0xc208051b00) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:228 +0x32 testing.tRunner(0xc208051b00, 0x7339d0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 111 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 112 [chan receive]: testing.(*T).Parallel(0xc208051b90) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestBadHeaders(0xc208051b90) /home/dmiles/go/src/github.com/danieltmiles/stompngo/misc_test.go:242 +0x35 testing.tRunner(0xc208051b90, 0x7339e8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 113 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 114 [chan receive]: testing.(*T).Parallel(0xc208051c20) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestNackErrors(0xc208051c20) /home/dmiles/go/src/github.com/danieltmiles/stompngo/nack_test.go:66 +0x35 testing.tRunner(0xc208051c20, 0x733a00) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 115 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 116 [chan receive]: testing.(*T).Parallel(0xc208051cb0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSendBasic(0xc208051cb0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/send_test.go:28 +0x35 testing.tRunner(0xc208051cb0, 0x733a18) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 117 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 118 [chan receive]: testing.(*T).Parallel(0xc208051d40) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSendMultiple(0xc208051d40) /home/dmiles/go/src/github.com/danieltmiles/stompngo/send_test.go:60 +0x32 testing.tRunner(0xc208051d40, 0x733a30) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 119 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 120 [chan receive]: testing.(*T).Parallel(0xc208051dd0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSendBytesBasic(0xc208051dd0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sendbytes_test.go:28 +0x35 testing.tRunner(0xc208051dd0, 0x733a48) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 121 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 122 [chan receive]: testing.(*T).Parallel(0xc208051e60) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSendBytesMultiple(0xc208051e60) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sendbytes_test.go:60 +0x32 testing.tRunner(0xc208051e60, 0x733a60) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 123 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 124 [chan receive]: testing.(*T).Parallel(0xc208051ef0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubNoSub(0xc208051ef0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:31 +0x35 testing.tRunner(0xc208051ef0, 0x733a78) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 125 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 126 [chan receive]: testing.(*T).Parallel(0xc208064000) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubNoIdOnce(0xc208064000) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:56 +0x35 testing.tRunner(0xc208064000, 0x733a90) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 127 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 128 [chan receive]: testing.(*T).Parallel(0xc208064090) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubNoIdTwice10(0xc208064090) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:90 +0x14c testing.tRunner(0xc208064090, 0x733aa8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 129 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 131 [chan receive]: testing.(*T).Parallel(0xc2080641b0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubUnsubBasic(0xc2080641b0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:215 +0x35 testing.tRunner(0xc2080641b0, 0x733ad8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 132 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 133 [chan receive]: testing.(*T).Parallel(0xc208064240) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubUnsubBasic10(0xc208064240) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:266 +0x12f testing.tRunner(0xc208064240, 0x733af0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 134 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 135 [chan receive]: testing.(*T).Parallel(0xc2080642d0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestSubEstablishSubscription(0xc2080642d0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/sub_test.go:309 +0x32 testing.tRunner(0xc2080642d0, 0x733b08) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 136 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 138 [chan receive]: testing.(*T).Parallel(0xc2080643f0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestTransErrors(0xc2080643f0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/trans_test.go:28 +0x35 testing.tRunner(0xc2080643f0, 0x733b38) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 139 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 140 [chan receive]: testing.(*T).Parallel(0xc208064480) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestTransSend(0xc208064480) /home/dmiles/go/src/github.com/danieltmiles/stompngo/trans_test.go:119 +0x35 testing.tRunner(0xc208064480, 0x733b50) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 141 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 142 [chan receive]: testing.(*T).Parallel(0xc208064510) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestTransSendRollback(0xc208064510) /home/dmiles/go/src/github.com/danieltmiles/stompngo/trans_test.go:168 +0x35 testing.tRunner(0xc208064510, 0x733b68) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 143 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 144 [chan receive]: testing.(*T).Parallel(0xc2080645a0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestTransMessageOrder(0xc2080645a0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/trans_test.go:235 +0x35 testing.tRunner(0xc2080645a0, 0x733b80) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 145 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 146 [chan receive]: testing.(*T).Parallel(0xc208064630) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestUnsubNoHdr(0xc208064630) /home/dmiles/go/src/github.com/danieltmiles/stompngo/unsub_test.go:49 +0x35 testing.tRunner(0xc208064630, 0x733b98) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 147 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 148 [chan receive]: testing.(*T).Parallel(0xc2080646c0) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestUnsubNoId(0xc2080646c0) /home/dmiles/go/src/github.com/danieltmiles/stompngo/unsub_test.go:77 +0x35 testing.tRunner(0xc2080646c0, 0x733bb0) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 149 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 150 [chan receive]: testing.(*T).Parallel(0xc208064750) /usr/local/go/src/pkg/testing/testing.go:388 +0x76 github.com/danieltmiles/stompngo.TestUnsubBadId(0xc208064750) /home/dmiles/go/src/github.com/danieltmiles/stompngo/unsub_test.go:104 +0x35 testing.tRunner(0xc208064750, 0x733bc8) /usr/local/go/src/pkg/testing/testing.go:422 +0x8b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:504 +0x8db

    goroutine 151 [chan receive]: testing.func·007() /usr/local/go/src/pkg/testing/testing.go:508 +0x5b created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:509 +0x999

    goroutine 145 [syscall]: runtime.goexit() /usr/local/go/src/pkg/runtime/proc.c:1445 exit status 2 FAIL github.com/danieltmiles/stompngo 0.039s

    Closed 
    opened by danieltmiles 5
  • Lack of detection of EOF (No automatic reconnection)

    Lack of detection of EOF (No automatic reconnection)

    Not sure how reconnection or detection of failed network connections is supposed to work.. .but...

    reader.go contains a bug in which it does not properly detect EOF.

    This may be by design, however if you close(c) after the for {} loop, the user and use the coma, ok ("msg, ok := <-r") pattern to detect when the channel is closed and attempt a reconnect.

    The fix is to close the input channel which will signal a closed channel to the receiver.

    ~ line 70 of func (c *Connection) reader() {

    70 fmt.Println("Dead connection") 71 close(c.input)

    Reconnection could be made automatic but it might be up to the caller to handle this also.

    Closed 
    opened by sigmonsays 4
  • Is this a potential bug of SetWriteDeadline?

    Is this a potential bug of SetWriteDeadline?

    Hi , I have read the source code of stompngo and find something hard to understand.

    Here's a reader go routine which can be set read timeout by conn.ReadDealLine

    func (c *Connection) setReadDeadline() {
    	if c.dld.rde && c.dld.rds {
    		_ = c.netconn.SetReadDeadline(time.Now().Add(c.dld.rdld))
    	}
    }
    

    The reader use c.dld.rde && c.dld.rds to check if read deadline will be set. Buf a writer use c.dld.wde && c.dld.dns to check if write deadline will be set. Should it use c.dld.wde && c.dld.wds instead ?

    func (c *Connection) wireWrite(d wiredata) {
    	f := &d.frame
    	// fmt.Printf("WWD01 f:[%v]\n", f)
    	switch f.Command {
    	case "\n": // HeartBeat frame
    		if c.dld.wde && c.dld.dns {
    			_ = c.netconn.SetWriteDeadline(time.Now().Add(c.dld.wdld))
    		}
    

    Looking forward to your reply

    opened by itomsawyer 3
  • Panic: non-positive interval for NewTicker

    Panic: non-positive interval for NewTicker

    I don't know why this occurred, but I got this error during one of my test runs:

    panic: non-positive interval for NewTicker
    time.NewTicker
        go/src/time/tick.go:32
    github.com/gmallard/stompngo.(*Connection).receiveTicker
        src/github.com/gmallard/stompngo/heartbeats.go:163
    github.com/gmallard/stompngo.(*Connection).initializeHeartBeats
        src/github.com/gmallard/stompngo/heartbeats.go:183
    

    It only happened to me once, so it's probably something transient. Just wanted to report it as this seems like something that would be very simple to check for so that it's prevented in the future.

    opened by sybrandy 3
  • Race in disconnect

    Race in disconnect

    Disconnect can block forever on line https://github.com/gmallard/stompngo/blob/dev/disconnect.go#L69 if the reader is shutdown before the disconnect receipt has been read.

    This can be shown by adding a sleep in reader (TestDiscRace will hang):

    diff --git a/conndisc_test.go b/conndisc_test.go
    index 1e5527d..bc95097 100644
    --- a/conndisc_test.go
    +++ b/conndisc_test.go
    @@ -306,3 +306,22 @@ func TestConnRespData(t *testing.T) {
                    }
            }
     }
    +
    +func TestDiscRace(t *testing.T) {
    +       t.Parallel()
    +       n, _ := openConn(t)
    +       ch := check11(TEST_HEADERS)
    +       c, _ := Connect(n, ch)
    +
    +       r := "my-receipt-001"
    +       e := c.Send(Headers{"destination", "my-dest", "receipt", r},
    +               "my-data")
    +       if e != nil {
    +               t.Errorf("Send: got error %v\n", e)
    +       }
    +       _ = <-c.MessageData
    +
    +       _ = c.Disconnect(empty_headers)
    +       _ = closeConn(t, n)
    +
    +}
    diff --git a/reader.go b/reader.go
    index 46ecc58..3ce0f60 100644
    --- a/reader.go
    +++ b/reader.go
    @@ -60,6 +60,8 @@ func (c *Connection) reader() {
    
                    c.log("RECEIVE", m.Command, m.Headers)
    
    +               time.Sleep(time.Second)
    +
                    select {
                    case q = <-c.rsd:
                    default:
    

    Suggested fix: shut down the reader later or close the input channel when the reader exits. or both.

    opened by serbaut 3
  • Use case in production environment

    Use case in production environment

    Hi @gmallard

    stompngo is a awesome project. I wonder is there any other use case in production environment. We have put it under production environment with rabbitmq and rabbitmq-stomp-websocket plugin, which can provide us a channel to push message from server to agents under a web app like connection.

    opened by itomsawyer 1
  • Potential blocking on unsubscribe with message in flight

    Potential blocking on unsubscribe with message in flight

    Per our discussion in stompngo_examples issue #2, I'm opening an issue in the main project. The concern is on what to do with in-flight messages received after or during an unsubscribe. The current use case I've been working with involves ActiveMQ with prefetch set, but could apply to any similar interaction with a STOMP server that sends more than one MESSAGE without requiring an ACK using either ackmode client or client-individual

    1. connect
    2. sub to queue q.1 with ackmode client and prefetch X where X is how many messages I need
    3. process X messages
    4. ACK the last message (which should be cumulative with ackmode client)
    5. unsubscribe
    6. repeat 2-5 with queues q.2, q.3, etc.

    The problem I'm running into is that the UNSUBSCRIBE right after the ACK seems to be causing messages to not get ACKed sometimes, and some of the later subscriptions are getting nothing at all. In examining this problem (which may or may not be related to the issue I'm submitting), I ran across the following scenario which I think needs to be at least mentioned in the documentation, if not fixed in the code somehow:

    1. Client subscribes to a destination, which creates a chan MessageData with a buffer size of c.scc (default: 1)
    //subscription.go
    if hid { // Client specified id
         c.subs[id] = make(chan MessageData, c.scc) // Assign subscription
    }
    
    1. Message(s) arrive with that destination specified in the subscription header and are picked up in the read loop here
    //reader.go
    if sid, ok := f.Headers.Contains("subscription"); ok {
         c.subsLock.Lock()
         c.subs[sid] <- d
         c.subsLock.Unlock()
    } else {
         c.input <- d
    }
    
    1. Client processes some messages or not, but there is still a message in the channel for this subscription.
    2. client unsubscribes, which causes the following
    //unsubscribe.go
    c.subsLock.Lock()                                                                                                                                                              defer c.subsLock.Unlock()
    // ...
    close(c.subs[sid])
    delete(c.subs, sid)
    
    1. Before c.subsLock.Lock() is called in the unsubscribe, another message arrives and is picked up by the reader goroutine.

    It seems that this would block. The unsubscribe wouldn't be able to get the subsLock, and the reader goroutine would be blocked trying to send to the subscription channel.

    opened by flowchartsman 27
Owner
Guy M. Allard
Guy M. Allard
Go server for STOMP message protocol

Stomper A Go message queue implementing the STOMP protocol. Done Frame parsing TODO Server connection protocol Define interface for queueing Implement

Tyler Darnell 4 Feb 1, 2022
go stomp server base on net/http

stompserver go stomp server base on "net/http" base on "net/http" and "golang.org/x/net/websocket" so use one port, you can be WebServer or StompServe

0xAAFF 0 Jul 13, 2022
A Go package for sending and receiving ethernet frames. Currently supporting Linux, Freebsd, and OS X.

ether ether is a go package for sending and receiving ethernet frames. Currently supported platform: BPF based OS X FreeBSD AF_PACKET based Linux Docu

Song Gao 77 Jun 20, 2022
rpc/v2 support for JSON-RPC 2.0 Specification.

rpc rpc/v2 support for JSON-RPC 2.0 Specification. gorilla/rpc is a foundation for RPC over HTTP services, providing access to the exported methods of

High Performance, Kubernetes Native Object Storage 3 Jul 4, 2021
TritonHTTP - A simple web server that implements a subset of the HTTP/1.1 protocol specification

TritonHTTP Spec Summary Here we provide a concise summary of the TritonHTTP spec. You should read the spec doc for more details and clarifications. HT

Boyu Chen 0 Mar 29, 2022
A MCBE Proxy supporting fast transfer and much more!

Downloads Pipelines Here you can find all the build please select the latest and click Artifacts

sun_proxy 29 Jul 22, 2022
A load balancer supporting multiple LB strategies written in Go

farely A load balancer supporting multiple LB strategies written in Go. Goal The goal of this project is purley educational, I started it as a brainst

Mehdi Cheracher 11 Aug 7, 2022
Powerful golang network framework, supporting FFAX Protocol

X.NET framework Install $ go get github.com/RealFax/XNET This is a high-performance network framework, currently only supports tcp and FFAX protocol U

Realfax Messenger 0 Nov 19, 2021
A structure generating tool for Minecraft Bedrock Edition that supporting various platforms

FastBuilder Phoenix Description FastBuilder is a structure generating tool for Minecraft Bedrock Edition that supporting various platforms. The Phoeni

null 1 Dec 10, 2021
null 11 Jun 23, 2022
screen sharing for developers https://screego.net/

screego/server screen sharing for developers Huge thanks to sipgate for sponsoring this project! Intro In the past I've had some problems sharing my s

screego 5k Sep 25, 2022
A golang library about socks5, supports all socks5 commands. That Provides server and client and easy to use. Compatible with socks4 and socks4a.

socks5 This is a Golang implementation of the Socks5 protocol library. To see in this SOCKS Protocol Version 5. This library is also compatible with S

chenhao zhang 41 Aug 17, 2022
A Realtime API Gateway used with NATS to build REST, real time, and RPC APIs, where all your clients are synchronized seamlessly.

Realtime API Gateway Synchronize Your Clients Visit Resgate.io for guides, live demos, and resources. Resgate is a Go project implementing a realtime

Resgate.io - Synchronize Your Clients 593 Sep 26, 2022
Dead simple reverse proxy for all your containerized needss

Whats this ? Pawxi is yet another reverse proxy designed with simplicity in mind. Born out of a certain users frustration at the complexity of setting

null 14 May 26, 2022
For your server and all of its waifus <3

waifud A few tools to help me manage and run virtual machines across a homelab cluster. waifud was made for my own personal use and I do not expect it

Christine Dodrill 77 Sep 28, 2022
All-in-one Network Gateway for Malware analysis

aio-gw [EXPERIMENTAL]: All-in-one Network Gateway for Malware analysis. currently at Alpha stage. HELP NEEDED: if you're keen to contribute to aio-gw,

Ali Mosajjal 2 Jan 30, 2022
The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the processor

server-pubsub The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the p

null 0 Dec 3, 2021
dshield-intelfeel-ips - print all IPs from the DShield API's Intelfeed to STDOUT

dshield-intelfeel-ips dshield-intelfeel-ips - print all IPs from the DShield API's Intelfeed to STDOUT Project Description Usage Description Installat

Patrick Cronin 1 Oct 20, 2021