mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-11-25 19:01:35 +00:00
80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
|
// Package ddp implements the MeteorJS DDP protocol over websockets. Fallback
|
||
|
// to longpolling is NOT supported (and is not planned on ever being supported
|
||
|
// by this library). We will try to model the library after `net/http` - right
|
||
|
// now the library is barebones and doesn't provide the pluggability of http.
|
||
|
// However, that's the goal for the package eventually.
|
||
|
package ddp
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// debugLog is true if we should log debugging information about the connection
|
||
|
var debugLog = true
|
||
|
|
||
|
// The main file contains common utility types.
|
||
|
|
||
|
// -------------------------------------------------------------------
|
||
|
|
||
|
// idManager provides simple incrementing IDs for ddp messages.
|
||
|
type idManager struct {
|
||
|
// nextID is the next ID for API calls
|
||
|
nextID uint64
|
||
|
// idMutex is a mutex to protect ID updates
|
||
|
idMutex *sync.Mutex
|
||
|
}
|
||
|
|
||
|
// newidManager creates a new instance and sets up resources.
|
||
|
func newidManager() *idManager {
|
||
|
return &idManager{idMutex: new(sync.Mutex)}
|
||
|
}
|
||
|
|
||
|
// newID issues a new ID for use in calls.
|
||
|
func (id *idManager) newID() string {
|
||
|
id.idMutex.Lock()
|
||
|
next := id.nextID
|
||
|
id.nextID++
|
||
|
id.idMutex.Unlock()
|
||
|
return fmt.Sprintf("%x", next)
|
||
|
}
|
||
|
|
||
|
// -------------------------------------------------------------------
|
||
|
|
||
|
// pingTracker tracks in-flight pings.
|
||
|
type pingTracker struct {
|
||
|
handler func(error)
|
||
|
timeout time.Duration
|
||
|
timer *time.Timer
|
||
|
}
|
||
|
|
||
|
// -------------------------------------------------------------------
|
||
|
|
||
|
// Call represents an active RPC call.
|
||
|
type Call struct {
|
||
|
ID string // The uuid for this method call
|
||
|
ServiceMethod string // The name of the service and method to call.
|
||
|
Args interface{} // The argument to the function (*struct).
|
||
|
Reply interface{} // The reply from the function (*struct).
|
||
|
Error error // After completion, the error status.
|
||
|
Done chan *Call // Strobes when call is complete.
|
||
|
Owner *Client // Client that owns the method call
|
||
|
}
|
||
|
|
||
|
// done removes the call from any owners and strobes the done channel with itself.
|
||
|
func (call *Call) done() {
|
||
|
delete(call.Owner.calls, call.ID)
|
||
|
select {
|
||
|
case call.Done <- call:
|
||
|
// ok
|
||
|
default:
|
||
|
// We don't want to block here. It is the caller's responsibility to make
|
||
|
// sure the channel has enough buffer space. See comment in Go().
|
||
|
if debugLog {
|
||
|
log.Println("rpc: discarding Call reply due to insufficient Done chan capacity")
|
||
|
}
|
||
|
}
|
||
|
}
|