Add a websocket session RPC.
This commit is contained in:
parent
6ac46f9e5f
commit
3c9d18d641
5 changed files with 68 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Copyright (c) 2014-2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -56,6 +56,15 @@ func NewNotifyNewTransactionsCmd(verbose *bool) *NotifyNewTransactionsCmd {
|
|||
}
|
||||
}
|
||||
|
||||
// SessionCmd defines the session JSON-RPC command.
|
||||
type SessionCmd struct{}
|
||||
|
||||
// NewSessionCmd returns a new instance which can be used to issue a session
|
||||
// JSON-RPC command.
|
||||
func NewSessionCmd() *SessionCmd {
|
||||
return &SessionCmd{}
|
||||
}
|
||||
|
||||
// StopNotifyNewTransactionsCmd defines the stopnotifynewtransactions JSON-RPC command.
|
||||
type StopNotifyNewTransactionsCmd struct{}
|
||||
|
||||
|
@ -158,6 +167,7 @@ func init() {
|
|||
MustRegisterCmd("notifynewtransactions", (*NotifyNewTransactionsCmd)(nil), flags)
|
||||
MustRegisterCmd("notifyreceived", (*NotifyReceivedCmd)(nil), flags)
|
||||
MustRegisterCmd("notifyspent", (*NotifySpentCmd)(nil), flags)
|
||||
MustRegisterCmd("session", (*SessionCmd)(nil), flags)
|
||||
MustRegisterCmd("stopnotifyblocks", (*StopNotifyBlocksCmd)(nil), flags)
|
||||
MustRegisterCmd("stopnotifynewtransactions", (*StopNotifyNewTransactionsCmd)(nil), flags)
|
||||
MustRegisterCmd("stopnotifyspent", (*StopNotifySpentCmd)(nil), flags)
|
||||
|
|
10
btcjson/chainsvrwsresults.go
Normal file
10
btcjson/chainsvrwsresults.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcjson
|
||||
|
||||
// SessionResult models the data from the session command.
|
||||
type SessionResult struct {
|
||||
SessionID uint64 `json:"sessionid"`
|
||||
}
|
|
@ -685,6 +685,7 @@ user. Click the method name for further details such as parameter and return in
|
|||
|8|[rescan](#rescan)|Rescan block chain for transactions to addresses and spent transaction outpoints.|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) |
|
||||
|9|[notifynewtransactions](#notifynewtransactions)|Send notifications for all new transactions as they are accepted into the mempool.|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)|
|
||||
|10|[stopnotifynewtransactions](#stopnotifynewtransactions)|Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.|None|
|
||||
|11|[session](#session)|Return details regarding a websocket client's current connection.|None|
|
||||
|
||||
<a name="WSExtMethodDetails" />
|
||||
**7.2 Method Details**<br />
|
||||
|
@ -815,6 +816,20 @@ user. Click the method name for further details such as parameter and return in
|
|||
|Returns|Nothing|
|
||||
[Return to Overview](#WSExtMethodOverview)<br />
|
||||
|
||||
***
|
||||
|
||||
<a name="session"/>
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|Method|session|
|
||||
|Notifications|None|
|
||||
|Parameters|None|
|
||||
|Description|Return a JSON object with details regarding a websocket client's current connection to the RPC server. This currently only includes the session ID, a random unsigned 64-bit integer that is created for each newly connected client. Session IDs may be used to verify that the current connection was not lost and subsequently reestablished.|
|
||||
|Returns|`{ (json object)`<br /> `"sessionid": n (numeric) the session ID`<br />`}`|
|
||||
|Example Return|`{`<br /> `"sessionid": 67089679842`<br />`}`|
|
||||
[Return to Overview](#WSExtMethodOverview)<br />
|
||||
|
||||
|
||||
<a name="Notifications" />
|
||||
### 8. Notifications (Websocket-specific)
|
||||
|
|
|
@ -525,6 +525,10 @@ var helpDescsEnUS = map[string]string{
|
|||
|
||||
// -------- Websocket-specific help --------
|
||||
|
||||
// Session help.
|
||||
"session--synopsis": "Return details regarding a websocket client's current connection session.",
|
||||
"sessionresult-sessionid": "The unique session ID for a client's websocket connection.",
|
||||
|
||||
// NotifyBlocksCmd help.
|
||||
"notifyblocks--synopsis": "Request notifications for whenever a block is connected or disconnected from the main (best) chain.",
|
||||
|
||||
|
@ -616,6 +620,7 @@ var rpcResultTypes = map[string][]interface{}{
|
|||
"verifymessage": []interface{}{(*bool)(nil)},
|
||||
|
||||
// Websocket commands.
|
||||
"session": []interface{}{(*btcjson.SessionResult)(nil)},
|
||||
"notifyblocks": nil,
|
||||
"stopnotifyblocks": nil,
|
||||
"notifynewtransactions": nil,
|
||||
|
|
|
@ -54,6 +54,7 @@ var wsHandlersBeforeInit = map[string]wsCommandHandler{
|
|||
"notifynewtransactions": handleNotifyNewTransactions,
|
||||
"notifyreceived": handleNotifyReceived,
|
||||
"notifyspent": handleNotifySpent,
|
||||
"session": handleSession,
|
||||
"stopnotifyblocks": handleStopNotifyBlocks,
|
||||
"stopnotifynewtransactions": handleStopNotifyNewTransactions,
|
||||
"stopnotifyspent": handleStopNotifySpent,
|
||||
|
@ -94,7 +95,12 @@ func (s *rpcServer) WebsocketHandler(conn *websocket.Conn, remoteAddr string,
|
|||
// Create a new websocket client to handle the new websocket connection
|
||||
// and wait for it to shutdown. Once it has shutdown (and hence
|
||||
// disconnected), remove it and any notifications it registered for.
|
||||
client := newWebsocketClient(s, conn, remoteAddr, authenticated, isAdmin)
|
||||
client, err := newWebsocketClient(s, conn, remoteAddr, authenticated, isAdmin)
|
||||
if err != nil {
|
||||
rpcsLog.Errorf("Failed to serve client %s: %v", remoteAddr, err)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
s.ntfnMgr.AddClient(client)
|
||||
client.Start()
|
||||
client.WaitForShutdown()
|
||||
|
@ -869,6 +875,11 @@ type wsClient struct {
|
|||
// false means its access is only to the limited set of RPC calls.
|
||||
isAdmin bool
|
||||
|
||||
// sessionID is a random ID generated for each client when connected.
|
||||
// These IDs may be queried by a client using the session RPC. A change
|
||||
// to the session ID indicates that the client reconnected.
|
||||
sessionID uint64
|
||||
|
||||
// verboseTxUpdates specifies whether a client has requested verbose
|
||||
// information about all new transactions.
|
||||
verboseTxUpdates bool
|
||||
|
@ -1383,13 +1394,19 @@ func (c *wsClient) WaitForShutdown() {
|
|||
// incoming and outgoing messages in separate goroutines complete with queueing
|
||||
// and asynchrous handling for long-running operations.
|
||||
func newWebsocketClient(server *rpcServer, conn *websocket.Conn,
|
||||
remoteAddr string, authenticated bool, isAdmin bool) *wsClient {
|
||||
remoteAddr string, authenticated bool, isAdmin bool) (*wsClient, error) {
|
||||
|
||||
return &wsClient{
|
||||
sessionID, err := wire.RandomUint64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := &wsClient{
|
||||
conn: conn,
|
||||
addr: remoteAddr,
|
||||
authenticated: authenticated,
|
||||
isAdmin: isAdmin,
|
||||
sessionID: sessionID,
|
||||
server: server,
|
||||
addrRequests: make(map[string]struct{}),
|
||||
spentRequests: make(map[wire.OutPoint]struct{}),
|
||||
|
@ -1398,6 +1415,7 @@ func newWebsocketClient(server *rpcServer, conn *websocket.Conn,
|
|||
sendChan: make(chan wsResponse, websocketSendBufferSize),
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// handleWebsocketHelp implements the help command for websocket connections.
|
||||
|
@ -1454,6 +1472,12 @@ func handleNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// handleSession implements the session command extension for websocket
|
||||
// connections.
|
||||
func handleSession(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||
return &btcjson.SessionResult{SessionID: wsc.sessionID}, nil
|
||||
}
|
||||
|
||||
// handleStopNotifyBlocks implements the stopnotifyblocks command extension for
|
||||
// websocket connections.
|
||||
func handleStopNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||
|
|
Loading…
Reference in a new issue