2016-05-04 07:03:36 +00:00
|
|
|
package libnmdc
|
|
|
|
|
2017-11-26 00:29:44 +00:00
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
)
|
|
|
|
|
2016-05-04 07:03:36 +00:00
|
|
|
type HubConnectionOptions struct {
|
2016-05-04 07:15:02 +00:00
|
|
|
Address HubAddress
|
|
|
|
SkipVerifyTLS bool // using a negative verb, because bools default to false
|
|
|
|
SkipAutoReconnect bool // as above
|
2017-11-22 07:04:15 +00:00
|
|
|
Self *UserInfo
|
2016-05-04 07:15:02 +00:00
|
|
|
NickPassword string
|
2017-11-26 00:29:44 +00:00
|
|
|
AdcPID string // blank: autogenerate
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPID() string {
|
|
|
|
pidBytes := make([]byte, 24)
|
|
|
|
n, err := rand.Read(pidBytes)
|
|
|
|
if err != nil {
|
|
|
|
panic(err) // Insufficient cryptographic randomness
|
|
|
|
}
|
|
|
|
|
|
|
|
if n != 24 {
|
|
|
|
panic("Insufficient cryptographic randomness")
|
|
|
|
}
|
|
|
|
|
|
|
|
return Base32(pidBytes)
|
2016-05-04 07:03:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (this *HubConnectionOptions) prepareConnection() *HubConnection {
|
|
|
|
if this.Self.ClientTag == "" {
|
|
|
|
this.Self.ClientTag = DEFAULT_CLIENT_TAG
|
2016-11-29 07:07:19 +00:00
|
|
|
this.Self.ClientVersion = DEFAULT_CLIENT_VERSION
|
|
|
|
}
|
|
|
|
|
|
|
|
// Shouldn't be blank either
|
|
|
|
if this.Self.ClientVersion == "" {
|
|
|
|
this.Self.ClientVersion = "0"
|
2016-05-04 07:03:36 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 00:29:44 +00:00
|
|
|
if this.AdcPID == "" {
|
|
|
|
this.AdcPID = NewPID()
|
|
|
|
}
|
|
|
|
|
2016-05-04 07:03:36 +00:00
|
|
|
hc := HubConnection{
|
|
|
|
Hco: this,
|
|
|
|
HubName: DEFAULT_HUB_NAME,
|
|
|
|
State: CONNECTIONSTATE_DISCONNECTED,
|
2016-05-08 00:33:49 +00:00
|
|
|
users: make(map[string]UserInfo),
|
2016-05-04 07:15:02 +00:00
|
|
|
|
|
|
|
autoReconnect: !this.SkipAutoReconnect,
|
2016-05-04 07:03:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &hc
|
|
|
|
}
|
|
|
|
|
2017-11-22 07:02:30 +00:00
|
|
|
// ConnectAsync connects to a hub server, and spawns a background goroutine to handle
|
|
|
|
// protocol messages. Events will be sent by channel to the supplied onEvent channel,
|
2016-05-04 07:15:02 +00:00
|
|
|
// the client is responsible for selecting off this.
|
2017-11-22 07:02:30 +00:00
|
|
|
func ConnectAsync(opts *HubConnectionOptions, onEvent chan HubEvent) *HubConnection {
|
|
|
|
hc := opts.prepareConnection()
|
2016-05-04 07:03:36 +00:00
|
|
|
hc.processEvent = func(ev HubEvent) {
|
2017-11-22 07:02:30 +00:00
|
|
|
onEvent <- ev
|
2016-05-04 07:03:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
go hc.worker()
|
|
|
|
return hc
|
|
|
|
}
|
|
|
|
|
2017-11-22 07:02:30 +00:00
|
|
|
// ConnectSync connects to a hub server, and blocks forever to handle protocol messages.
|
2016-05-04 07:15:02 +00:00
|
|
|
// Client code should supply an event handling function as hco.OnEventSync.
|
2017-11-22 07:02:30 +00:00
|
|
|
func ConnectSync(opts *HubConnectionOptions, onEvent func(hub *HubConnection, ev HubEvent)) {
|
|
|
|
hc := opts.prepareConnection()
|
2016-11-29 06:39:47 +00:00
|
|
|
hc.processEvent = func(ev HubEvent) {
|
2017-11-22 07:02:30 +00:00
|
|
|
onEvent(hc, ev)
|
2016-11-29 06:39:47 +00:00
|
|
|
}
|
2016-05-04 07:03:36 +00:00
|
|
|
hc.worker()
|
|
|
|
}
|