Rework writer deadline handling.
[stompngo.git] / connect.go
blob91f14c93f1bb92515c47c9c65d420f84700d5d86
1 //
2 // Copyright © 2011-2017 Guy M. Allard
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 package stompngo
19 import (
20 "bufio"
21 // "fmt"
22 "net"
23 "time"
27 Primary STOMP Connect.
29 For STOMP 1.1+ the Headers parameter MUST contain the headers required
30 by the specification. Those headers are not magically inferred.
32 Example:
33 // Obtain a network connection
34 n, e := net.Dial(NetProtoTCP, "localhost:61613")
35 if e != nil {
36 // Do something sane ...
38 h := stompngo.Headers{} // A STOMP 1.0 connection request
39 c, e := stompngo.Connect(n, h)
40 if e != nil {
41 // Do something sane ...
43 // Use c
45 Example:
46 // Obtain a network connection
47 n, e := net.Dial(NetProtoTCP, "localhost:61613")
48 if e != nil {
49 // Do something sane ...
51 h := stompngo.Headers{HK_ACCEPT_VERSION, "1.1",
52 HK_HOST, "localhost"} // A STOMP 1.1 connection
53 c, e := stompngo.Connect(n, h)
54 if e != nil {
55 // Do something sane ...
57 // Use c
59 func Connect(n net.Conn, h Headers) (*Connection, error) {
60 if h == nil {
61 return nil, EHDRNIL
63 if e := h.Validate(); e != nil {
64 return nil, e
66 if _, ok := h.Contains(HK_RECEIPT); ok {
67 return nil, ENORECPT
69 ch := h.Clone()
70 //fmt.Printf("CONDB01\n")
71 c := &Connection{netconn: n,
72 input: make(chan MessageData, 1),
73 output: make(chan wiredata),
74 connected: false,
75 session: "",
76 protocol: SPL_10,
77 subs: make(map[string]*subscription),
78 DisconnectReceipt: MessageData{},
79 ssdc: make(chan struct{}),
80 wtrsdc: make(chan struct{}),
81 scc: 1,
82 dld: &deadlineData{}}
84 // Bsaic metric data
85 c.mets = &metrics{st: time.Now()}
87 // Assumed for now
88 c.MessageData = c.input
90 // Check that the cilent wants a version we support
91 if e := c.checkClientVersions(h); e != nil {
92 return c, e
94 //fmt.Printf("CONDB02\n")
95 // OK, put a CONNECT on the wire
96 c.wtr = bufio.NewWriter(n) // Create the writer
97 go c.writer() // Start it
98 f := Frame{CONNECT, ch, NULLBUFF} // Create actual CONNECT frame
99 r := make(chan error) // Make the error channel for a write
100 c.output <- wiredata{f, r} // Send the CONNECT frame
101 e := <-r // Retrieve any error
103 if e != nil {
104 close(c.ssdc) // Shutdown, we are done with errors
105 return c, e
107 //fmt.Printf("CONDB03\n")
109 e = c.connectHandler(ch)
110 if e != nil {
111 close(c.ssdc) // Shutdown , we are done with errors
112 return c, e
114 //fmt.Printf("CONDB04\n")
115 // We are connected
116 go c.reader()
118 return c, e