src/stomp.nim
author Mahlon E. Smith <mahlon@martini.nu>
Sun, 04 Apr 2021 15:56:16 -0700
changeset 8 363f275588ea
parent 7 9c5ce539b081
child 9 ad53c6500712
permissions -rw-r--r--
Fix value encoding to conform to spec. Thanks to Marcelo Módolo <marcelo.rmodolo@gmail.com> for the heads up.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     1
# vim: set et nosta sw=4 ts=4 ft=nim : 
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     2
#
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
     3
# Copyright (c) 2016-2021, Mahlon E. Smith <mahlon@martini.nu>
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     4
# All rights reserved.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     5
# Redistribution and use in source and binary forms, with or without
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     6
# modification, are permitted provided that the following conditions are met:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     7
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     8
#     * Redistributions of source code must retain the above copyright
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
     9
#       notice, this list of conditions and the following disclaimer.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    10
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    11
#     * Redistributions in binary form must reproduce the above copyright
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    12
#       notice, this list of conditions and the following disclaimer in the
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    13
#       documentation and/or other materials provided with the distribution.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    14
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    15
#     * Neither the name of Mahlon E. Smith nor the names of his
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    16
#       contributors may be used to endorse or promote products derived
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    17
#       from this software without specific prior written permission.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    18
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    19
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    20
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    21
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    22
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    23
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    24
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    25
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    26
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    27
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    28
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    29
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    30
## Overview
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    31
## ============
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    32
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    33
## This is a pure-nim client library for interacting with Stomp 1.2
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    34
## compliant messaging brokers.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    35
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    36
## https://stomp.github.io/stomp-specification-1.2.html
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    37
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    38
## Stomp is a simple protocol for message passing between clients, using a central
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    39
## broker.  It is a subset of other more elaborate protocols (like AMQP), supporting
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    40
## only the most used features of common brokers.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    41
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    42
## Because this library is pure-nim, there are no external dependencies.  If you
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    43
## can compile a nim binary, you can participate in advanced messaging between processes.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    44
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    45
## A list of broker support for Stomp can be found here:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    46
## https://stomp.github.io/implementations.html.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    47
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    48
## This library has been tested with recent versions of RabbitMQ.  If it
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    49
## works for you with another broker, please let the author know.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    50
##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    51
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    52
import
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    53
    strutils,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    54
    nativesockets,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    55
    net,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    56
    os,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    57
    times,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    58
    uri
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    59
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    60
const
7
9c5ce539b081 Version bump.
Mahlon E. Smith <mahlon@laika.com>
parents: 6
diff changeset
    61
    VERSION = "0.1.2" ## The current program version.
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    62
    NULL    = "\x00"  ## The NULL character.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    63
    CR      = "\r"    ## The carriage return character.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    64
    CRLF    = "\r\n"  ## Carriage return + Line feed (EOL).
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    65
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    66
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    67
# Exceptions
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    68
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    69
type
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    70
    StompError* = object of ValueError ## A generic Stomp error state.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    71
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    72
    StompClient* = ref object of RootObj ## An object that represents a connection to a Stomp compatible server.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    73
        socket:         Socket ## The socket object attached to this client.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    74
        connected*:     bool ## Is the client currently connected?
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    75
        uri*:           Uri ## The URI used to instantiate this client.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    76
        username:       string ## The Stomp server user, if any.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    77
        password:       string ## The Stomp server password, if any.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    78
        host:           string ## The host or IP address to connect to.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    79
        port:           Port ## Optional, if Stomp is on a non-default port.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    80
        vhost:          string ## Parsed from the URI path, a Stomp "virtual host".
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    81
        timeout*:       int ## Global socket timeout.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    82
        last_msgtime*:  Time ## Timestamp of last seen server message.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    83
        options:        tuple[ heartbeat: int ] ## Any supported client options, derived from the URI query string.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    84
        subscriptions*: seq[ string ] ## Registered client subscriptions. Array position is the ID.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    85
        transactions*:  seq[ string ] ## Any currently open transactions.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    86
        serverinfo:     seq[ tuple[name: string, value: string] ] ## Server metadata, populated upon a successful connection.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    87
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    88
        connected_callback*:        proc ( client: StompClient, response: StompResponse ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    89
        error_callback*:            proc ( client: StompClient, response: StompResponse ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    90
        heartbeat_callback*:        proc ( client: StompClient, response: StompResponse ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    91
        message_callback*:          proc ( client: StompClient, response: StompResponse ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    92
        missed_heartbeat_callback*: proc ( client: StompClient ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    93
        receipt_callback*:          proc ( client: StompClient, response: StompResponse ): void
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    94
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    95
    StompResponse* = ref object of RootObj ## A parsed packet from a Stomp server.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    96
        headers:  seq[ tuple[name: string, value: string] ] ## Any headers in the response.  Access with the `[]` proc.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    97
        frame*:   string ## The Stomp frame type.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    98
        payload*: string ## The message body, if any.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
    99
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   100
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   101
# convenience
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   102
proc printf( formatstr: cstring ) {.header: "<stdio.h>", varargs.}
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   103
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   104
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   105
proc encode( str: string ): string =
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   106
    ## Encode value value strings per the "Value Encoding" section
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   107
    ## of the Stomp 1.2 spec.
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   108
    result = str
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   109
    result = result.
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   110
        replace( "\r", "\\r" ).
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   111
        replace( "\n", "\\n" ).
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   112
        replace( "\\", "\\\\" ).
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   113
        replace( ":", "\\c" )
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   114
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   115
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   116
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   117
# R E S P O N S E
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   118
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   119
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   120
proc is_eol( s: string ): bool =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   121
    ## Convenience method, returns **true** if string is a Stomp EOF.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   122
    return s == CR or s == CRLF
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   123
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   124
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   125
proc parse_headers( response: StompResponse, c: StompClient ): int =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   126
    ## Parse response headers from a stream.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   127
    ## Returns the content length of the response body, or 0.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   128
    result = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   129
    var line = ""
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   130
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   131
    c.socket.readline( line, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   132
    while not line.is_eol:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   133
        if defined( debug ): printf " <-- %s\n", line
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   134
        var header = line.split( ":" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   135
        if header.len < 2: break
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   136
        response.headers.add( (header[0], header[1]) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   137
        if cmpIgnoreCase( header[0], "content-length" ) == 0: result = header[1].parse_int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   138
        c.socket.readline( line, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   139
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   140
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   141
proc parse_payload( response: StompResponse, c: StompClient, bodylength = 0 ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   142
    ## Parse message payload from a stream.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   143
    let bufsize = 8192
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   144
    var
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   145
        buf  = ""
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   146
        data = ""
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   147
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   148
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   149
    # If we already know the length of the body, just perform a buffered read.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   150
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   151
    if bodylength > 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   152
        var
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   153
            readtotal = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   154
            readamt   = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   155
            remaining = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   156
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   157
        while readtotal != bodylength:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   158
            remaining = bodylength - readtotal
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   159
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   160
            if remaining < bufsize:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   161
                readamt = remaining
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   162
            else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   163
                readamt = bufsize
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   164
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   165
            buf = newString( readamt )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   166
            readtotal = readtotal + c.socket.recv( buf, readamt, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   167
            data = data & buf
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   168
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   169
        # Eat the NULL terminator.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   170
        discard c.socket.recv( buf, 1, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   171
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   172
    # Inefficient path.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   173
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   174
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   175
        while buf != NULL:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   176
            discard c.socket.recv( buf, 1, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   177
            data = data & buf
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   178
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   179
    response.payload = data
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   180
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   181
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   182
proc newStompResponse( c: StompClient ): StompResponse =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   183
    ## Initialize a response object, which parses and contains
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   184
    ## the Stomp headers and any additional important data from
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   185
    ## the broker socket.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   186
    new( result )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   187
    result.headers = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   188
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   189
    # Get the frame type, record last seen server activity time.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   190
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   191
    var line = ""
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   192
    c.socket.readline( line, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   193
    c.last_msgtime = get_time()
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   194
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   195
    # Heartbeat packets (empties.)
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   196
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   197
    # This could -also- parse optional EOLs from the prior
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   198
    # message (after the NULL separator), but since it is a no-op,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   199
    # this seems harmless.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   200
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   201
    if line.is_eol:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   202
        result.frame = "HEARTBEAT"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   203
        return result
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   204
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   205
    # All other types.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   206
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   207
    result.frame = line
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   208
    if defined( debug ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   209
        printf " <-- %s\n", line
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   210
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   211
    # Parse headers and body.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   212
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   213
    var length = result.parse_headers( c )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   214
    if result.frame == "MESSAGE" or result.frame == "ERROR":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   215
        result.parse_payload( c, length )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   216
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   217
    # If the response -could- have a body, the NULL has already
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   218
    # been removed from the stream while we checked for one.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   219
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   220
    if result.payload.len > 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   221
        if result.payload == NULL: # We checked for a body, but there was none.
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   222
            result.payload = ""
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   223
            if defined( debug ): printf " <--\n <-- ^@\n\n"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   224
        else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   225
            if defined( debug ): printf " <--\n <-- (payload)^@\n\n"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   226
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   227
    # Otherwise, pop off the NULL terminator now.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   228
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   229
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   230
        discard c.socket.recv( line, 1, c.timeout )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   231
        if defined( debug ): printf " <--\n <-- ^@\n\n"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   232
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   233
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   234
proc `$`*( r: StompResponse ): string =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   235
    ## Represent a Stomp response as a string.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   236
    result = r.frame & ": " & $r.headers
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   237
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   238
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   239
proc `[]`*( response: StompResponse, key: string ): string =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   240
    ## Get a specific header from a Stomp response.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   241
    for header in response.headers:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   242
        if cmpIgnoreCase( key, header.name ) == 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   243
            return header.value
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   244
    return ""
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   245
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   246
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   247
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   248
# C A L L B A C K S
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   249
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   250
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   251
proc default_error_callback( c: StompClient, response: StompResponse ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   252
    ## Something bad happened.  Disconnect from the server, build an error message,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   253
    ## and raise an exception.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   254
    c.socket.close
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   255
    c.connected = false
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   256
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   257
    var detail = response.payload
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   258
    var msg    = response[ "message" ]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   259
    if $detail[ ^1 ] == "\n": detail = detail[ 0 .. ^2 ] # chomp
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   260
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   261
    if detail.len > 0: msg = msg & " (" & detail & ")"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   262
    raise newException( StompError, "ERROR: " & msg )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   263
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   264
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   265
proc default_missed_heartbeat_callback( c: StompClient ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   266
    ## Timeout while connected to the broker.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   267
    c.socket.close
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   268
    c.connected = false
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   269
    raise newException( StompError, "Heartbeat timeout.  Last activity: " & $c.last_msgtime )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   270
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   271
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   272
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   273
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   274
# C L I E N T
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   275
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   276
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   277
proc newStompClient*( s: Socket, uri: string ): StompClient =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   278
    ## Create a new Stomp client object from a preexisting **socket**,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   279
    ## and a stomp **URI** string.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   280
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   281
    ## .. code-block:: nim
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   282
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   283
    ##    var socket = newSocket()
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   284
    ##    var stomp  = newStompClient( socket, "stomp://test:test@example.com/vhost" )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   285
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   286
    ## or if connecting with SSL, when compiled with -d:ssl:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   287
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   288
    ## .. code-block:: nim
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   289
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   290
    ##    var socket = newSocket()
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   291
    ##    let sslContext = newContext( verifyMode = CVerifyNone )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   292
    ##    sslContext.wrapSocket(socket)
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   293
    ##    var stomp = newStompClient( socket, "stomp+ssl://test:test@example.com/vhost" )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   294
    ##
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   295
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   296
    let
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   297
        uri   = parse_uri( uri )
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   298
        vhost = if uri.path.len > 1: uri.path.strip( chars = {'/'}, trailing = false ) else: uri.path
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   299
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   300
    new( result )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   301
    result.socket        = s
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   302
    result.connected     = false
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   303
    result.uri           = uri
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   304
    result.username      = uri.username
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   305
    result.password      = uri.password
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   306
    result.host          = uri.hostname
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   307
    result.vhost         = vhost
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   308
    result.timeout       = 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   309
    result.subscriptions = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   310
    result.transactions  = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   311
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   312
    # Parse any supported options in the query string.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   313
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   314
    for pairs in result.uri.query.split( '&' ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   315
        let opt = pairs.split( '=' )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   316
        try:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   317
            case opt[0]:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   318
                of "heartbeat":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   319
                    result.options.heartbeat = opt[1].parse_int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   320
                else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   321
                    discard
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   322
        except IndexError, ValueError:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   323
            discard
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   324
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   325
    # Set default STOMP port if otherwise unset.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   326
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   327
    if not result.uri.scheme.contains( "stomp" ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   328
        raise newException( StompError, "Unknown scheme: " & result.uri.scheme  )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   329
    var port: int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   330
    if result.uri.port == "":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   331
        if result.uri.scheme.contains( "+ssl" ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   332
            port = 61614
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   333
        else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   334
            port = 61613
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   335
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   336
        port = result.uri.port.parse_int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   337
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   338
    result.port = Port( port )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   339
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   340
    # Decode URI encoded slashes for vhosts.
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   341
    result.vhost = result.vhost.
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   342
        replace( "%2f", "/" ).
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   343
        replace( "%2F", "/" ).
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   344
        replace( "//", "/" )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   345
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   346
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   347
proc socksend( c: StompClient, data: string ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   348
    ## Send data on the connected socket with optional debug output.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   349
    c.socket.send( data )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   350
    if defined( debug ): printf " --> %s", data
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   351
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   352
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   353
proc finmsg( c: StompClient ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   354
    ## Send data on the connected socket with optional debug output.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   355
    c.socket.send( CRLF & NULL & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   356
    if defined( debug ): printf " --> \n --> ^@\n\n"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   357
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   358
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   359
proc `[]`*( c: StompClient, key: string ): string =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   360
    ## Get a specific value from the server metadata, set during the initial connection.
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   361
    if not c.connected: return ""
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   362
    for header in c.serverinfo:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   363
        if cmpIgnoreCase( key, header.name ) == 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   364
            return header.value
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   365
    return ""
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   366
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   367
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   368
proc `$`*( c: StompClient ): string =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   369
    ## Represent the stomp client as a string, after masking the password.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   370
    let uri = ( $c.uri ).replace( ":" & c.uri.password & "@", "@" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   371
    result = "(NimStomp v" & VERSION & ( if c.connected: " connected" else: " not connected" ) & " to " & uri
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   372
    if not ( c[ "server" ] == "" ): result.add( " --> " & c["server"] )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   373
    result.add( ")" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   374
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   375
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   376
proc connect*( c: StompClient ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   377
    ## Establish a connection to the Stomp server.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   378
    if c.connected: return
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   379
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   380
    var headers: seq[ tuple[name: string, value: string] ] = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   381
    headers.add( ("accept-version", "1.2") )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   382
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   383
    # Stomp 1.2 requires the Host: header.  Use the path as a vhost if
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   384
    # supplied, otherwise use the hostname of the server.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   385
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   386
    if c.vhost != "":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   387
        headers.add( ("host", c.vhost) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   388
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   389
        headers.add( ("host", c.host) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   390
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   391
    if c.username != "": headers.add( ("login", c.username) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   392
    if c.password != "": headers.add( ("passcode", c.password) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   393
    if c.options.heartbeat > 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   394
        let heartbeat = c.options.heartbeat * 1000
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   395
        headers.add( ("heart-beat", "0," & $heartbeat) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   396
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   397
    # Connect the socket and send the headers off.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   398
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   399
    c.socket.connect( c.host, c.port )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   400
    c.socksend( "CONNECT" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   401
    for header in headers:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   402
        c.socksend( header.name & ":" & header.value & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   403
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   404
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   405
    # Retreive and copy server metadata to client object.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   406
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   407
    var response = newStompResponse( c )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   408
    c.serverinfo = response.headers
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   409
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   410
    if response.frame != "CONNECTED":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   411
        if not isNil( c.error_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   412
            c.error_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   413
        else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   414
            c.default_error_callback( response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   415
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   416
        c.connected = true
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   417
        if not isNil( c.connected_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   418
            c.connected_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   419
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   420
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   421
proc disconnect*( c: StompClient ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   422
    ## Break down the connection to the Stomp server nicely.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   423
    if not c.connected: return
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   424
    c.socksend( "DISCONNECT" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   425
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   426
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   427
    c.socket.close
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   428
    c.connected = false
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   429
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   430
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   431
proc add_txn( c: StompClient ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   432
    ## Add a transaction header if there is only a single open txn.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   433
    if c.transactions.len != 1: return
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   434
    c.socksend( "transaction:" & c.transactions[0] & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   435
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   436
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   437
proc send*( c: StompClient,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   438
            destination: string,
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   439
            message:     string = "",
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   440
            contenttype: string = "",
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   441
            headers:     seq[ tuple[name: string, value: string] ] = @[] ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   442
    ## Send a **message** to **destination**.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   443
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   444
    ## A Content-Length header is automatically and always included.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   445
    ## A **contenttype** is optional, but strongly recommended.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   446
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   447
    ## Additionally, a transaction ID is automatically added if there is only
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   448
    ## one transaction active.  If you need to attach this message to a particular
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   449
    ## transaction ID, you'll need to add it yourself with the user defined
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   450
    ## **headers**.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   451
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   452
    if not c.connected: raise newException( StompError, "Client is not connected." )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   453
    c.socksend( "SEND" & CRLF )
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   454
    c.socksend( "destination:" & destination.encode & CRLF )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   455
    c.socksend( "content-length:" & $message.len & CRLF )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   456
    if not ( contenttype == "" ): c.socksend( "content-type:" & contenttype & CRLF )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   457
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   458
    # Add custom headers.  Add transaction header if one isn't manually
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   459
    # present (and a transaction is open.)
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   460
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   461
    var txn_seen = false
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   462
    for header in headers:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   463
        if header.name == "transaction": txn_seen = true
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   464
        c.socksend( header.name & ":" & header.value.encode & CRLF )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   465
    if not txn_seen: c.add_txn
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   466
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   467
    if message == "":
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   468
        c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   469
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   470
        c.socket.send( CRLF & message & NULL )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   471
        if defined( debug ): printf " -->\n --> (payload)^@\n\n"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   472
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   473
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   474
proc subscribe*( c: StompClient,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   475
            destination: string,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   476
            ack        = "auto",
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   477
            id:        string = "",
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   478
            headers:   seq[ tuple[name: string, value: string] ] = @[] ): void =
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   479
    ## Subscribe to messages at **destination**.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   480
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   481
    ## Setting **ack** to "client" or "client-individual" enables client ACK/NACK mode.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   482
    ## In this mode, incoming messages aren't considered processed by
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   483
    ## the server unless they receive ACK.  By default, the server
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   484
    ## considers the message processed if a client simply accepts it.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   485
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   486
    ## You may optionally add any additional **headers** the server may support.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   487
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   488
    if not c.connected: raise newException( StompError, "Client is not connected." )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   489
    c.socksend( "SUBSCRIBE" & CRLF )
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   490
    c.socksend( "destination:" & destination.encode & CRLF )
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   491
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   492
    if id == "":
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   493
        c.socksend( "id:" & $c.subscriptions.len & CRLF )
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   494
    else:
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   495
        c.socksend( "id:" & id & CRLF )
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   496
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   497
    if ack == "client" or ack == "client-individual":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   498
        c.socksend( "ack:" & ack & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   499
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   500
        if ack != "auto": raise newException( StompError, "Unknown ack type: " & ack )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   501
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   502
    for header in headers:
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   503
        c.socksend( header.name & ":" & header.value.encode & CRLF )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   504
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   505
    c.subscriptions.add( destination )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   506
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   507
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   508
proc unsubscribe*( c: StompClient,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   509
            destination: string,
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   510
            headers:     seq[ tuple[name: string, value: string] ] = @[] ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   511
    ## Unsubscribe from messages at **destination**.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   512
    ## You may optionally add any additional **headers** the server may support.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   513
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   514
    if not c.connected: raise newException( StompError, "Client is not connected." )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   515
    var
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   516
        sub_id: int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   517
        i = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   518
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   519
    # Find the ID of the subscription.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   520
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   521
    for sub in c.subscriptions:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   522
        if sub == destination:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   523
            sub_id = i
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   524
            break
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   525
        i = i + 1
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   526
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   527
    c.socksend( "UNSUBSCRIBE" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   528
    c.socksend( "id:" & $sub_id & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   529
    for header in headers:
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   530
        c.socksend( header.name & ":" & header.value.encode & CRLF )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   531
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   532
    c.subscriptions[ sub_id ] = ""
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   533
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   534
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   535
proc begin*( c: StompClient, txn: string ): void =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   536
    ## Begin a new transaction on the broker, using **txn** as the identifier.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   537
    c.socksend( "BEGIN" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   538
    c.socksend( "transaction:" & txn & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   539
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   540
    c.transactions.add( txn )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   541
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   542
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   543
proc commit*( c: StompClient, txn: string = "" ): void =
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   544
    ## Finish a specific transaction **txn**, or the most current if unspecified.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   545
    var transaction = txn
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   546
    if transaction == "" and c.transactions.len > 0: transaction = c.transactions.pop
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   547
    if transaction == "": return
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   548
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   549
    c.socksend( "COMMIT" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   550
    c.socksend( "transaction:" & transaction & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   551
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   552
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   553
    # Remove the transaction from the queue.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   554
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   555
    var new_transactions: seq[ string ] = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   556
    for txn in c.transactions:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   557
        if txn != transaction: new_transactions.add( txn )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   558
    c.transactions = new_transactions
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   559
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   560
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   561
proc abort*( c: StompClient, txn: string = "" ): void =
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   562
    ## Cancel a specific transaction **txn**, or the most current if unspecified.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   563
    var transaction = txn
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   564
    if transaction == "" and c.transactions.len > 0: transaction = c.transactions.pop
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   565
    if transaction == "": return
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   566
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   567
    c.socksend( "ABORT" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   568
    c.socksend( "transaction:" & transaction & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   569
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   570
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   571
    # Remove the transaction from the queue.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   572
    #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   573
    var new_transactions: seq[ string ] = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   574
    for txn in c.transactions:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   575
        if txn != transaction: new_transactions.add( txn )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   576
    c.transactions = new_transactions
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   577
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   578
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   579
proc ack*( c: StompClient, id: string, transaction: string = "" ): void =
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   580
    ## Acknowledge message **id**.  Optionally, attach this acknowledgement
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   581
    ## to a specific **transaction** -- if there's only one active, it is
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   582
    ## added automatically.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   583
    c.socksend( "ACK" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   584
    c.socksend( "id:" & id & CRLF )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   585
    if not ( transaction == "" ):
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   586
        c.socksend( "transaction:" & transaction & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   587
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   588
        c.add_txn
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   589
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   590
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   591
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   592
proc nack*( c: StompClient, id: string, transaction: string = "" ): void =
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   593
    ## Reject message **id**.  Optionally, attach this rejection to a
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   594
    ## specific **transaction** -- if there's only one active, it is
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   595
    ## added automatically.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   596
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   597
    ## Subscribe to a queue with ACK mode enabled, and reject the message
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   598
    ## on error:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   599
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   600
    ## .. code-block:: nim
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   601
    ##    
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   602
    ##  stomp.subscribe( "/queue/test", "client-individual" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   603
    ##  FIXME: attach procs
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   604
    ##  stomp.wait_for_messages
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   605
    ##
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   606
    c.socksend( "NACK" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   607
    c.socksend( "id:" & id & CRLF )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   608
    if not ( transaction == "" ):
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   609
        c.socksend( "transaction:" & transaction & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   610
    else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   611
        c.add_txn
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   612
    c.finmsg
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   613
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   614
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   615
proc wait_for_messages*( c: StompClient, loop=true ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   616
    ## Enter a blocking select loop, dispatching to the appropriate proc
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   617
    ## for the received message type.   Return after a single message
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   618
    ## is received if **loop** is set to **false**.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   619
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   620
    if not c.connected: raise newException( StompError, "Client is not connected." )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   621
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   622
    while true:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   623
        var
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   624
            timeout: int
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   625
            fds = @[ c.socket.get_fd ]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   626
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   627
        # Check for missed heartbeats, with an additional second
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   628
        # of wiggle-room.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   629
        #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   630
        if c.options.heartbeat > 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   631
             timeout = ( c.options.heartbeat + 1 ) * 1000
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   632
        else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   633
            timeout = -1
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   634
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   635
        if select_read( fds, timeout ) == 0: # timeout, only happens if heartbeating missed
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   636
            if not isNil( c.missed_heartbeat_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   637
                c.missed_heartbeat_callback( c )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   638
            else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   639
                c.default_missed_heartbeat_callback
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   640
            if loop: continue else: break
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   641
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   642
        let response = newStompResponse( c )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   643
        case response.frame:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   644
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   645
            of "HEARTBEAT":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   646
                if not isNil( c.heartbeat_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   647
                    c.heartbeat_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   648
                continue
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   649
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   650
            of "RECEIPT":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   651
                if not isNil( c.receipt_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   652
                    c.receipt_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   653
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   654
            of "MESSAGE":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   655
                if not isNil( c.message_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   656
                    c.message_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   657
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   658
            of "ERROR":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   659
                if not isNil( c.error_callback ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   660
                    c.error_callback( c, response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   661
                else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   662
                    c.default_error_callback( response )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   663
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   664
            else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   665
                if defined( debug ):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   666
                    echo "Strange broker frame: " & response.repr
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   667
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   668
        if not loop: break
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   669
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   670
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   671
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   672
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   673
# T E S T S
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   674
#-------------------------------------------------------------------
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   675
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   676
# Functional (rather than unit) tests.  Requires a Stomp compatible broker.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   677
# This was tested against RabbitMQ 3.5.3 and 3.6.0.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   678
# 3.6.0 was -so- much faster.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   679
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   680
# First start up a message receiver:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   681
#   ./stomp receiver [stomp-uri] [subscription-destination]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   682
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   683
# then run another process, to publish stuff:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   684
#   ./stomp publisher [stomp-uri] [publish-destination]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   685
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   686
# An example with an AMQP "direct" exchange, and an exclusive queue:
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   687
#   ./stomp publisher stomp://test:test@localhost/%2F?heartbeat=10 /exchange/test
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   688
#   ./stomp receiver  stomp://test:test@localhost/%2F?heartbeat=10 /exchange/test
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   689
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   690
# Then just let 'er run.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   691
#
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   692
# You can also run a naive benchmark (deliveries/sec):
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   693
#
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   694
#   ./stomp benchmark stomp://test:test@localhost%2F /exchange/test
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   695
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   696
# It will set messages to require acknowledgement, and nack everything, causing
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   697
# a delivery loop for 10 seconds.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   698
#
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   699
when isMainModule:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   700
    let expected = 8
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   701
    var
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   702
        socket   = newSocket()
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   703
        messages: seq[ StompResponse ] = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   704
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   705
    let usage = """
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   706
First start up a message receiver:
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   707
  ./stomp receiver [stomp-uri] [subscription-destination]
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   708
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   709
then run another process, to publish stuff:
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   710
  ./stomp publisher [stomp-uri] [publish-destination]
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   711
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   712
An example with an AMQP "direct" exchange, and an exclusive queue:
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   713
  ./stomp publisher stomp://test:test@localhost/%2F?heartbeat=10 /exchange/test
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   714
  ./stomp receiver  stomp://test:test@localhost/%2F?heartbeat=10 /exchange/test
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   715
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   716
Then just let 'er run.
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   717
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   718
You can also run a naive benchmark (deliveries/sec):
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   719
6
7d977f308c75 Incorporate a series of patches from Zack Smith.
Zach Smith <zd@zdsmith.com>
parents: 4
diff changeset
   720
  ./stomp benchmark stomp://test:test@localhost/%2F /exchange/test
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   721
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   722
It will set messages to require acknowledgement, and nack everything, causing
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   723
a delivery loop for 10 seconds.
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   724
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   725
With older version of RabbitMQ, If your vhost requires slashes, you'll
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   726
need to URI escape: /%2Ftest
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   727
"""
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   728
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   729
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   730
    if paramCount() != 3: quit usage
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   731
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   732
    var stomp = newStompClient( socket, paramStr(2) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   733
    stomp.connect
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   734
    echo stomp
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   735
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   736
    case paramStr(1):
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   737
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   738
        of "benchmark":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   739
            echo "* Running for 10 seconds.  Compile with -d:debug to see the Stomp conversation."
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   740
            var count = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   741
            var start = get_time()
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   742
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   743
            proc incr( c: StompClient, r: StompResponse ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   744
                let id = r["ack"]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   745
                count = count + 1
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   746
                c.nack( id )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   747
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   748
            stomp.message_callback = incr
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   749
            stomp.subscribe( paramStr(3), "client" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   750
            stomp.send( paramStr(3), "hi." )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   751
            while get_time() < start + 10.seconds:
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   752
                stomp.wait_for_messages( false )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   753
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   754
            printf "* Processed %d messages in 10 seconds.\n", count
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   755
            stomp.disconnect
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   756
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   757
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   758
        # Store incoming messages, ensure their contents match our expected behavior.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   759
        #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   760
        of "receiver":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   761
            var heartbeats = 0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   762
            echo "* Waiting on messages from publisher.  Compile with -d:debug to see the Stomp conversation."
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   763
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   764
            proc receive_message( c: StompClient, r: StompResponse ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   765
                messages.add( r )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   766
                case r.frame:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   767
                    of "RECEIPT":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   768
                        discard
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   769
                    of "MESSAGE":
8
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   770
                        discard r.payload
363f275588ea Fix value encoding to conform to spec.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
   771
                        discard r[ "ack" ]
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   772
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   773
            proc seen_heartbeat( c: StompClient, r: StompResponse ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   774
                heartbeats = heartbeats + 1
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   775
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   776
            stomp.message_callback   = receive_message
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   777
            stomp.receipt_callback   = receive_message
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   778
            stomp.heartbeat_callback = seen_heartbeat
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   779
            stomp.subscribe( paramStr(3) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   780
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   781
            # Populate the messages sequence with the count of expected messages.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   782
            for i in 1..expected: stomp.wait_for_messages( false )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   783
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   784
            # Assertions on the results!
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   785
            #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   786
            doAssert( messages.len == expected )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   787
            doAssert( messages[0].payload == "" )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   788
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   789
            doAssert( messages[1].payload == "Hello world!" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   790
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   791
            doAssert( messages[2].payload == "Dumb.\n\n" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   792
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   793
            doAssert( messages[3].payload == "Hello again." )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   794
            doAssert( messages[3][ "content-type" ] == "text/plain" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   795
            doAssert( messages[3][ "Content-Type" ] == "text/plain" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   796
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   797
            doAssert( messages[4][ "x-custom" ] == "yum" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   798
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   799
            doAssert( messages[5][ "receipt" ] == "42" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   800
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   801
            doAssert( messages[6].payload == "transaction!" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   802
            doAssert( messages[7].payload == "transaction 2" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   803
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   804
            stomp.disconnect
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   805
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   806
            if heartbeats > 0:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   807
                printf "* Tests passed! %d heartbeats seen.", heartbeats
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   808
            else:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   809
                echo "* Tests passed!"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   810
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   811
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   812
        # Publish a variety of messages with various options.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   813
        # Pause momentarily between sends(), as brokers -might- impose
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   814
        # rate limits and/or message dropping.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   815
        #
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   816
        of "publisher":
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   817
            echo "* Publishing to receiver.  Compile with -d:debug to see the Stomp conversation."
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   818
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   819
            # Simple, no frills event.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   820
            stomp.send( paramStr(3) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   821
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   822
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   823
            # Event with a body.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   824
            stomp.send( paramStr(3), "Hello world!" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   825
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   826
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   827
            # Event that doesn't contain a content-length.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   828
            # (Note, the broker may elect to add one on your behalf, which is a good thing...
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   829
            # but invalidates this test.)
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   830
            stomp.socksend( "SEND" & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   831
            stomp.socksend( "destination:" & paramStr(3) & CRLF & CRLF )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   832
            stomp.socksend( "Dumb.\n\n" & NULL )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   833
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   834
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   835
            # Content-Type
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   836
            stomp.send( paramStr(3), "Hello again.", "text/plain" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   837
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   838
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   839
            # Custom headers.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   840
            var headers: seq[ tuple[ name: string, value: string ] ] = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   841
            headers.add( ("x-custom", "yum") )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   842
            stomp.send( paramStr(3), "Hello again.", "text/plain", headers )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   843
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   844
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   845
            # Receipt requests.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   846
            proc receive_receipt( c: StompClient, r: StompResponse ) =
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   847
                messages.add( r )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   848
            headers = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   849
            headers.add( ("receipt", "42") )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   850
            stomp.send( paramStr(3), "Hello again.", "text/plain", headers )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   851
            stomp.receipt_callback = receive_receipt
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   852
            stomp.wait_for_messages( false )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   853
            doAssert( messages[0]["receipt-id"] == "42" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   854
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   855
            # Aborted transaction.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   856
            stomp.begin( "test-abort" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   857
            for i in 1..3:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   858
                stomp.send( paramStr(3), "Message: " & $i )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   859
            stomp.abort
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   860
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   861
            # Committed transaction.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   862
            stomp.begin( "test-commit" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   863
            stomp.send( paramStr(3), "transaction!" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   864
            stomp.commit
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   865
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   866
            # Mixed transactions.
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   867
            for i in 1..3:
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   868
                headers = @[]
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   869
                headers.add( ("transaction", "test-" & $i ) )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   870
                stomp.begin( "test-" & $i )
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   871
                stomp.send( paramStr(3), "transaction " & $i, "", headers )
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   872
                sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   873
            stomp.abort( "test-1" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   874
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   875
            stomp.commit( "test-2" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   876
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   877
            stomp.abort( "test-3" )
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   878
            sleep 500
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   879
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   880
            stomp.disconnect
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   881
            echo "* Tests passed!"
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   882
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   883
        else:
4
2f4e88604125 Re-arrange for nimble, update to Nim 0.19.
Mahlon E. Smith <mahlon@martini.nu>
parents: 0
diff changeset
   884
            quit usage
0
52e9f64937bf Initial commit.
Mahlon E. Smith <mahlon@laika.com>
parents:
diff changeset
   885