Class: VistaRPC4r::RPCBrokerConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/vistarpc4r/rpc_broker_connection.rb

Constant Summary collapse

CHUNK_TYPE_HEADER =

Header chunk types

"1"
CHUNK_TYPE_RPC =
"2"
CHUNK_TYPE_SECURITY =
"3"
CHUNK_TYPE_COMMAND =
"4"
CHUNK_TYPE_DATA =
"5"
XWB_HEADER =
"[XWB]"
VISTA_RPC_VERSION =

Header and protocol info

"1"
VISTA_RPC_TYPE_CMD =
"0"
VISTA_RPC_TYPE_RPC =
"1"
VISTA_RPC_LENV =
3
VISTA_RPC_LENV_STR =
"3"
VISTA_RPC_RETURN_DATA =
"0"
VISTA_RPC_NO_RETURN_DATA =
"1"
END_MARKER =
4
PARAM_LITERAL_MARKER =

Parameter types

"0"
PARAM_REFERENCE_MARKER =
"1"
PARAM_LIST_MARKER =
"2"
PARAM_GLOBAL_MARKER =
"3"
PARAM_EMPTY_MARKER =
"4"

Instance Method Summary collapse

Constructor Details

#initialize(host, port, access, verify, debug = FALSE) ⇒ RPCBrokerConnection

Returns a new instance of RPCBrokerConnection.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 32

def initialize(host, port, access, verify, debug=FALSE)
  @sentConnect = false
  @signedOn = false
  @host=host
  @port=port
  @access=access
  @verify=verify
  if debug
    @loglevel=2
  else
    @loglevel=0
  end
  @token=nil
  @socket = nil
  @encryptedAV = nil
  @writeBuffer = String.new
  @duz = "0"
  @currentContext = nil
  @lastvistaerror = nil

end

Instance Method Details

#call(rpcname, responsetype, args = nil) ⇒ Object

Call the RPC function

rpcname = String containing name of RPC
args = Array of arguments 0-based
response type = one of the types in RPCResponse
returns RPCResponse


143
144
145
146
147
148
149
150
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 143

def call(rpcname, responsetype, args=nil)
  rpc = VistaRPC.new(rpcname, responsetype)
  if !args.nil?
    rpc.params = args
  end
  rpcresponse = execute(rpc)
  return rpcresponse
end

#call_a(rpcname, args = nil) ⇒ Object

Call the RPC function expecting to receive a array of string ARRAY

rpcname = String containing name of RPC
args = Array of arguments 0-based
returns Array


175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 175

def call_a(rpcname, args=nil)
  rpc = VistaRPC.new(rpcname, RPCResponse::ARRAY)
  if !args.nil?
    rpc.params = args
  end
  rpcresponse = execute(rpc)
  if rpcresponse.nil?
    return nil
  end
  if !rpcresponse.error_message.nil?
    @lastvistaerror = rpcresponse.error_message
  end
  return rpcresponse.value
end

#call_s(rpcname, args = nil) ⇒ Object

Call the RPC function expecting to receive a string or SINGLE_VALUE

rpcname = String containing name of RPC
args = Array of arguments 0-based
returns String


156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 156

def call_s(rpcname, args=nil)
  rpc = VistaRPC.new(rpcname, RPCResponse::SINGLE_VALUE)
  if !args.nil?
    rpc.params = args
  end
  rpcresponse = execute(rpc)
  if rpcresponse.nil?
    return nil
  end
  if !rpcresponse.error_message.nil?
    @lastvistaerror = rpcresponse.error_message
  end
  return rpcresponse.value
end

#closeObject

close tries to gracefully end the VistA session. If socket is already dead, will return nil



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 81

def close()
  if isConnected()
    if @sentConnect
      @sentConnect = false  # set in connect()
      @signedOn=false  # set in signOn() inside connect()
      bye = VistaRPC.new("#BYE#", RPCResponse::SINGLE_VALUE, true)
      retval = execute(bye)
      @socket.close()
      @socket = nil
      @duz = "0"
      @lastvistaerror = nil
      @currentContext = nil
      return retval
    end
  end
end

#connectObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 54

def connect
  retVal = true
  if isConnected()
    warn " already connected, closing first"
    close
  end
  @socket = TCPSocket.open(@host, @port)    # Connect
  #            socket.setTcpNoDelay(true)
  tcpConnect = VistaRPC.new("TCPConnect", RPCResponse::SINGLE_VALUE, true)
  tcpConnect.params[0]= @socket.addr[4]  # local IP address
  tcpConnect.params[1]= "0" # callback port ?
  tcpConnect.params[2]= "OVID"
  connectResponse = execute(tcpConnect)
  if (connectResponse == nil || connectResponse.value == nil || connectResponse.value == "reject")
    raise "Handshake error" 
  end
  if (connectResponse.error_message != nil)
    raise "RPC Error: " + connectResponse.error_message 
  end
  @sentConnect = true
  
  signOn()
  retVal = ()
  return retVal
end

#execute(rpc) ⇒ Object

execute differs from RPCBrokerConnection - We want the application to know about eof execute will return nil if ioerror most likely unexpected EOFError



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 116

def execute(rpc)
  @lastvistaerror = nil
  retVal = executeOnce(rpc)
  if (retVal == nil && @signedOn) 
    #maybe some reconnect logic
    if (rpc.name == "#BYE#")
      # We're disconnecting anyway
      return nil
    end
    # attempt to log back on
    #if (connect())
    #  if (@currentContext != nil) 
    #    tempcontext = @currentContext
    #    @currentContext = nil
    #    setContext(tempcontext)
    #  end
    #  retVal = executeOnce(rpc)
    #end
  end
  return retVal
end

#forcecloseObject

force the broker into the pre connect state. Use if close returns nil



99
100
101
102
103
104
105
106
107
108
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 99

def forceclose
  @sentConnect = false  # set in connect()
  @signedOn=false  # set in signOn() inside connect()
  @socket.close()
  @socket = nil
  @duz = "0"
  @currentContext = nil
  @lastvistaerror=nil
  return true
end

#getDUZObject



217
218
219
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 217

def getDUZ
  return @duz
end

#isConnectedObject



110
111
112
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 110

def isConnected()
  return @socket != nil
end

#lastvistaerrorObject

if call_a or call_s return nil, you can check to see if there was a VistA error message



191
192
193
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 191

def lastvistaerror
  return @lastvistaerror
end

#loglevel(level) ⇒ Object

set log level 0= off, 1= informational, 2=debug



222
223
224
225
226
227
228
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 222

def loglevel(level)
  if level < 0 or level > 2
    return nil
  end
  @loglevel = level
  return @loglevel
end

#setContext(context) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/vistarpc4r/rpc_broker_connection.rb', line 195

def setContext(context)
  if (context == @currentContext)
    warn "context is already set to " + context + "..."
    return
  end
  if (@currentContext != nil) 
    warn "changing context from " + @currentContext + " to " + context
  end
  
  #puts "Setting context to: " + context
  xwbCreateContext = VistaRPC.new("XWB CREATE CONTEXT", RPCResponse::SINGLE_VALUE)
  encryptedContext = xwbCreateContext.encrypt(context)
  xwbCreateContext.params[0] = encryptedContext
  response = execute(xwbCreateContext)
  if (response == nil || response.error_message != nil)
    raise "XWB CREATE CONTEXT failed: " + response.error_message
  end
  @currentContext = context
  return response
end