Documentation
¶
Index ¶
- Constants
- Variables
- func AddPendingAuthorization(client *ClientInfo, challenge string, callback AuthCallback)
- func AddToSliceCl(ary *[]*ClientInfo, val *ClientInfo) bool
- func AddToSliceS(ary *[]string, val string) bool
- func CountSubscriptions(channels []string) int
- func DispatchC2SCommand(conn *websocket.Conn, client *ClientInfo, msg ClientMessage)
- func DumpBacklogData()
- func GenerateKeys(outputFile, serverID, theirPublicStr string)
- func GetAllTopics() []string
- func GetCounterPeriod(at time.Time) (start time.Time, end time.Time)
- func GetHLLFilename(at time.Time) string
- func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request)
- func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request)
- func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request)
- func HTTPGetSubscriberCount(w http.ResponseWriter, r *http.Request)
- func HTTPHandleRootURL(w http.ResponseWriter, r *http.Request)
- func HTTPListAllTopics(w http.ResponseWriter, r *http.Request)
- func HTTPSayOK(w http.ResponseWriter, _ *http.Request)
- func HTTPShowHLL(w http.ResponseWriter, r *http.Request)
- func HTTPShowStatistics(w http.ResponseWriter, _ *http.Request)
- func HTTPWriteHLL(w http.ResponseWriter, _ *http.Request)
- func MarshalClientMessage(clientMessage interface{}) (int, []byte, error)
- func ProxyHandler(route ProxyRoute) *httputil.ReverseProxy
- func PublishToAll(msg ClientMessage, rl rate.Limiter) (count int)
- func PublishToChannel(channel string, msg ClientMessage, rl rate.Limiter) (count int)
- func PublishToMultiple(channels []string, msg ClientMessage, rl rate.Limiter) (count int)
- func RemoveFromSliceCl(ary *[]*ClientInfo, val *ClientInfo) bool
- func RemoveFromSliceS(ary *[]string, val string) bool
- func RunSocketConnection(conn *websocket.Conn)
- func SendBacklogForChannel(client *ClientInfo, channel string)
- func SendBacklogForNewClient(client *ClientInfo)
- func SendMessage(conn *websocket.Conn, msg ClientMessage)
- func SetBuildStamp(buildTime, buildHash string)
- func SetupServerAndHandle(config *ConfigFile, serveMux *http.ServeMux)
- func Shutdown(wg *sync.WaitGroup)
- func SubscribeChannel(client *ClientInfo, channelName string)
- func SubscribeGlobal(client *ClientInfo)
- func UnmarshalClientMessage(data []byte, _ int, v interface{}) (err error)
- func UnsubscribeAll(client *ClientInfo)
- func UnsubscribeSingleChat(client *ClientInfo, channelName string)
- type AuthCallback
- type AuthInfo
- type ClientInfo
- type ClientMessage
- func C2SEmoticonUses(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
- func C2SHandleBunchedCommand(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func C2SHandleRemoteCommand(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func C2SHello(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (_ ClientMessage, err error)
- func C2SPing(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
- func C2SReady(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func C2SSetUser(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func C2SSubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func C2SSurvey(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
- func C2STrackFollow(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (_ ClientMessage, err error)
- func C2SUnsubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
- func (cm *ClientMessage) ArgumentsAsInt() (int1 int64, err error)
- func (cm *ClientMessage) ArgumentsAsString() (string1 string, err error)
- func (cm *ClientMessage) ArgumentsAsStringAndBool() (str string, flag bool, err error)
- func (cm *ClientMessage) ArgumentsAsStringAndInt() (string1 string, int int64, err error)
- func (cm *ClientMessage) ArgumentsAsTwoStrings() (string1, string2 string, err error)
- func (cm ClientMessage) Reply(cmd Command, args interface{}) ClientMessage
- func (cm ClientMessage) ReplyJSON(cmd Command, argsJSON string) ClientMessage
- type ClientVersion
- type Command
- type CommandHandler
- type ConfigFile
- type ErrBackendNotOK
- type ErrForwardedFromBackend
- type LastSavedMessage
- type PendingAuthorization
- type PeriodUniqueUsers
- type ProxyRoute
- type StatsData
- type StringPool
- type SubscriberList
- type UuidHash
Examples ¶
Constants ¶
const AuthChannel = "#" + AuthChannelName
const AuthChannelName = "frankerfacezauthorizer"
const AuthCommand = "AUTH"
const AuthorizationFailedErrorString = "Failed to verify your Twitch username."
const AuthorizationNeededError = "You must be signed in to use that command."
const CounterPrecision uint8 = 12
const NegativeOne = ^uint64(0)
const ReapingDelay = 1 * time.Minute
const StatsDataVersion = 8
StatsDataVersion is the version of the StatsData struct.
const UsersDailyFmt = "daily-%d-%d-%d.gob" // d-m-y
Variables ¶
var AnonymousClientID = uuid.FromStringOrNil("683b45e4-f853-4c45-bf96-7d799cc93e34")
var Backend *backendInfo
var BannerHTML []byte
BannerHTML is the content served to web browsers viewing the socket server website. Memes go here.
var CachedLSMLock sync.RWMutex
var CachedLastMessages = make(map[Command]map[string]LastSavedMessage)
CachedLastMessages is of CacheTypeLastOnly. Not actually cleaned up by reaper goroutine every ~hour.
var ChatSubscriptionInfo map[string]*SubscriberList = make(map[string]*SubscriberList)
var ChatSubscriptionLock sync.RWMutex
var CloseFirstMessageNotHello = websocket.CloseError{ Text: "Error - the first message sent must be a 'hello'", Code: websocket.ClosePolicyViolation, }
CloseFirstMessageNotHello is the termination reason
var CloseGoingAway = websocket.CloseError{Code: websocket.CloseGoingAway, Text: "server restarting"}
CloseGoingAway is sent when the server is restarting.
var CloseGotBinaryMessage = websocket.CloseError{Code: websocket.CloseUnsupportedData, Text: "got binary packet"}
CloseGotBinaryMessage is the termination reason when the client sends a binary websocket frame.
var CloseNonUTF8Data = websocket.CloseError{ Code: websocket.CloseUnsupportedData, Text: "Non UTF8 data recieved. Network corruption likely.", }
var CloseRebalance = websocket.CloseError{Code: websocket.CloseGoingAway, Text: "kicked for rebalancing, please select a new server"}
CloseRebalance is sent when the server has too many clients and needs to shunt some to another server.
var CloseTimedOut = websocket.CloseError{Code: 3003, Text: "no ping replies for 5 minutes"}
CloseTimedOut is the termination reason when the client fails to send or respond to ping frames.
var CloseTooManyBufferedMessages = websocket.CloseError{Code: websocket.CloseMessageTooBig, Text: "too many pending messages"}
CloseTooManyBufferedMessages is the termination reason when the sending thread buffers too many messages.
var CommandCounter = make(chan Command, 10)
CommandCounter is a channel for race-free counting of command usage.
var CounterLocation *time.Location = time.FixedZone("UTC-5", int((time.Hour*-5)/time.Second))
var ErrAuthorizationNeeded = errors.New("Must authenticate Twitch username to use this command")
ErrAuthorizationNeeded is emitted when the backend replies with HTTP 401.
Indicates that an attempt to validate `ClientInfo.TwitchUsername` should be attempted.
var ErrExpectedSingleInt = errors.New("Error: Expected single integer as arguments.")
ErrExpectedSingleInt is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrExpectedSingleString = errors.New("Error: Expected single string as arguments.")
ErrExpectedSingleString is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrExpectedStringAndBool = errors.New("Error: Expected array of string, bool as arguments.")
ErrExpectedStringAndBool is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrExpectedStringAndInt = errors.New("Error: Expected array of string, int as arguments.")
ErrExpectedStringAndInt is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrExpectedStringAndIntGotFloat = errors.New("Error: Second argument was a float, expected an integer.")
ErrExpectedStringAndIntGotFloat is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrExpectedTwoStrings = errors.New("Error: Expected array of string, string as arguments.")
ErrExpectedTwoStrings is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
var ErrProtocolGeneric error = fatalDecodeError("FFZ Socket protocol error.")
ErrProtocolGeneric is sent in a ErrorCommand Reply.
var ErrProtocolNegativeMsgID error = fatalDecodeError("FFZ Socket protocol error: negative or zero message ID.")
ErrProtocolNegativeMsgID is sent in a ErrorCommand Reply when a negative MessageID is received.
var GlobalSubscriptionInfo []*ClientInfo
var GlobalSubscriptionLock sync.RWMutex
var PendingAuthLock sync.Mutex
var PendingAuths []PendingAuthorization
var ResponseSuccess = ClientMessage{Command: SuccessCommand}
ResponseSuccess is a Reply ClientMessage with the MessageID not yet filled out.
var SocketUpgrader = websocket.Upgrader{ ReadBufferSize: 160, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { origin := r.Header.Get("Origin") if origin == "" || !Configuration.UseOriginChecks { return true } for _, allowedOrigin := range Configuration.AllowedOrigins { if strings.Contains(origin, allowedOrigin) { return true } } return false }, }
SocketUpgrader is the websocket.Upgrader currently in use.
var Statistics = newStatsData()
Statistics is several variables that get incremented during normal operation of the server. Its structure should be versioned as it is exposed via JSON.
Note as to threaded access - this is soft/fun data and not critical to data integrity. Fix anything that -race turns up, but otherwise it's not too much of a problem.
var StopAcceptingConnectionsCh = make(chan struct{})
StopAcceptingConnectionsCh is closed while the server is shutting down.
Functions ¶
func AddPendingAuthorization ¶
func AddPendingAuthorization(client *ClientInfo, challenge string, callback AuthCallback)
func AddToSliceCl ¶
func AddToSliceCl(ary *[]*ClientInfo, val *ClientInfo) bool
func AddToSliceS ¶
func CountSubscriptions ¶
func DispatchC2SCommand ¶
func DispatchC2SCommand(conn *websocket.Conn, client *ClientInfo, msg ClientMessage)
DispatchC2SCommand handles a C2S Command in the provided ClientMessage. It calls the correct CommandHandler function, catching panics. It sends either the returned Reply ClientMessage, setting the correct messageID, or sends an ErrorCommand
func GenerateKeys ¶
func GenerateKeys(outputFile, serverID, theirPublicStr string)
GenerateKeys generates a new NaCl keypair for the server and writes out the default configuration file.
func GetAllTopics ¶
func GetAllTopics() []string
func GetCounterPeriod ¶
GetCounterPeriod calculates the start and end timestamps for the HLL measurement period that includes the 'at' timestamp.
func GetHLLFilename ¶
GetHLLFilename returns the filename for the saved HLL whose measurement period covers the given time.
func HTTPBackendCachedPublish ¶
func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request)
HTTPBackendCachedPublish handles the /cached_pub route. It publishes a message to clients, and then updates the in-server cache for the message.
The 'channel' parameter is a comma-separated list of topics to publish the message to. The 'args' parameter is the JSON-encoded command data. If the 'delete' parameter is present, an entry is removed from the cache instead of publishing a message. If the 'expires' parameter is not specified, the message will not expire (though it is only kept in-memory).
func HTTPBackendDropBacklog ¶
func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request)
func HTTPBackendUncachedPublish ¶
func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request)
HTTPBackendUncachedPublish handles the /uncached_pub route. The backend can POST here to publish a message to clients with no caching. The POST arguments are `cmd`, `args`, `channel`, and `scope`. If "scope" is "global", then "channel" is not used.
func HTTPGetSubscriberCount ¶
func HTTPGetSubscriberCount(w http.ResponseWriter, r *http.Request)
HTTPGetSubscriberCount handles the /get_sub_count route. It replies with the number of clients subscribed to a pub/sub topic. A "global" option is not available, use fetch(/stats).CurrentClientCount instead.
func HTTPHandleRootURL ¶
func HTTPHandleRootURL(w http.ResponseWriter, r *http.Request)
HTTPHandleRootURL is the http.HandleFunc for requests on `/`. It either uses the SocketUpgrader or writes out the BannerHTML.
func HTTPListAllTopics ¶
func HTTPListAllTopics(w http.ResponseWriter, r *http.Request)
func HTTPSayOK ¶
func HTTPSayOK(w http.ResponseWriter, _ *http.Request)
HTTPSayOK replies with 200 and a body of "ok\n".
func HTTPShowHLL ¶
func HTTPShowHLL(w http.ResponseWriter, r *http.Request)
func HTTPShowStatistics ¶
func HTTPShowStatistics(w http.ResponseWriter, _ *http.Request)
HTTPShowStatistics handles the /stats endpoint. It writes out the Statistics object as indented JSON.
func HTTPWriteHLL ¶
func HTTPWriteHLL(w http.ResponseWriter, _ *http.Request)
func MarshalClientMessage ¶
returns payloadType, data, err
Example ¶
var cm ClientMessage = ClientMessage{ MessageID: -1, Command: "do_authorize", Arguments: "1234567890", } payloadType, data, err := MarshalClientMessage(&cm) fmt.Println(err) fmt.Println(payloadType == websocket.TextMessage) fmt.Println(string(data))
Output: <nil> true -1 do_authorize "1234567890"
func ProxyHandler ¶
func ProxyHandler(route ProxyRoute) *httputil.ReverseProxy
ProxyHandler sets up a ReverseProxy for serving content on a route.
func PublishToAll ¶
func PublishToAll(msg ClientMessage, rl rate.Limiter) (count int)
func PublishToChannel ¶
func PublishToChannel(channel string, msg ClientMessage, rl rate.Limiter) (count int)
func PublishToMultiple ¶
func PublishToMultiple(channels []string, msg ClientMessage, rl rate.Limiter) (count int)
func RemoveFromSliceCl ¶
func RemoveFromSliceCl(ary *[]*ClientInfo, val *ClientInfo) bool
func RemoveFromSliceS ¶
func RunSocketConnection ¶
RunSocketConnection contains the main run loop of a websocket connection.
First, it sets up the channels, the ClientInfo object, and the pong frame handler. It starts the reader goroutine pointing at the newly created channels. The function then enters the run loop (a `for{select{}}`). The run loop is broken when an object is received on errorChan, or if `hello` is not the first C2S Command.
After the run loop stops, the function launches a goroutine to drain client.MessageChannel, signals the reader goroutine to stop, unsubscribes from all pub/sub channels, waits on MsgChannelKeepalive (remember, the messages are being drained), and finally closes client.MessageChannel (which ends the drainer goroutine).
func SendBacklogForChannel ¶
func SendBacklogForChannel(client *ClientInfo, channel string)
func SendBacklogForNewClient ¶
func SendBacklogForNewClient(client *ClientInfo)
SendBacklogForNewClient sends any backlog data relevant to a new client. This should be done when the client sends a `ready` message. This will only send data for CacheTypePersistent and CacheTypeLastOnly because those do not involve timestamps.
func SendMessage ¶
func SendMessage(conn *websocket.Conn, msg ClientMessage)
SendMessage sends a ClientMessage over the websocket connection with a timeout. If marshalling the ClientMessage fails, this function will panic.
func SetBuildStamp ¶
func SetBuildStamp(buildTime, buildHash string)
SetBuildStamp should be called from the main package to identify the git build hash and build time.
func SetupServerAndHandle ¶
func SetupServerAndHandle(config *ConfigFile, serveMux *http.ServeMux)
SetupServerAndHandle starts all background goroutines and registers HTTP listeners on the given ServeMux. Essentially, this function completely preps the server for a http.ListenAndServe call. (Uses http.DefaultServeMux if `serveMux` is nil.)
func SubscribeChannel ¶
func SubscribeChannel(client *ClientInfo, channelName string)
func SubscribeGlobal ¶
func SubscribeGlobal(client *ClientInfo)
func UnmarshalClientMessage ¶
UnmarshalClientMessage unpacks websocket TextMessage into a ClientMessage provided in the `v` parameter.
Example ¶
sourceData := []byte("100 hello [\"ffz_3.5.30\",\"898b5bfa-b577-47bb-afb4-252c703b67d6\"]") var cm ClientMessage err := UnmarshalClientMessage(sourceData, websocket.TextMessage, &cm) fmt.Println(err) fmt.Println(cm.MessageID) fmt.Println(cm.Command) fmt.Println(cm.Arguments)
Output: <nil> 100 hello [ffz_3.5.30 898b5bfa-b577-47bb-afb4-252c703b67d6]
func UnsubscribeAll ¶
func UnsubscribeAll(client *ClientInfo)
UnsubscribeAll will unsubscribe the client from all channels, AND clear the CurrentChannels / WatchingChannels fields.
Locks:
- read lock to top-level maps
- write lock to SubscriptionInfos
- write lock to ClientInfo
func UnsubscribeSingleChat ¶
func UnsubscribeSingleChat(client *ClientInfo, channelName string)
Types ¶
type AuthCallback ¶
type AuthCallback func(client *ClientInfo, successful bool)
type ClientInfo ¶
type ClientInfo struct { // The client ID. // This must be written once by the owning goroutine before the struct is passed off to any other goroutines. ClientID uuid.UUID // The client's literal version string. // This must be written once by the owning goroutine before the struct is passed off to any other goroutines. VersionString string Version ClientVersion // Set after a successful hello message. HelloOK bool // This mutex protects writable data in this struct. // If it seems to be a performance problem, we can split this. Mutex sync.Mutex // Info about the client's username and whether or not we have verified it. AuthInfo RemoteAddr net.Addr // Username validation nonce. ValidationNonce string // The list of chats this client is currently in. // Protected by Mutex. CurrentChannels []string // True if the client has already sent the 'ready' command ReadyComplete bool // Closed when the client is shutting down. MsgChannelIsDone <-chan struct{} // Take out an Add() on this during a command if you need to call Send() later. MsgChannelKeepalive sync.WaitGroup // contains filtered or unexported fields }
func (*ClientInfo) Send ¶
func (client *ClientInfo) Send(msg ClientMessage) bool
Send a message to the client. Drops if buffer is full.
func (*ClientInfo) StartAuthorization ¶
func (client *ClientInfo) StartAuthorization(callback AuthCallback)
type ClientMessage ¶
type ClientMessage struct { // Message ID. Increments by 1 for each message sent from the client. // When replying to a command, the message ID must be echoed. // When sending a server-initiated message, this is -1. MessageID int `json:"m"` // The command that the client wants from the server. // When sent from the server, the literal string 'True' indicates success. // Before sending, a blank Command will be converted into SuccessCommand. Command Command `json:"c"` // Result of json.Unmarshal on the third field send from the client Arguments interface{} `json:"a"` // contains filtered or unexported fields }
func C2SEmoticonUses ¶
func C2SEmoticonUses(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
C2SEmoticonUses implements the `emoticon_uses` C2S Command. msg.Arguments are in the JSON format of [1]map[emoteID]map[ChatroomName]float64.
func C2SHandleBunchedCommand ¶
func C2SHandleBunchedCommand(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
C2SHandleBunchedCommand handles C2S Commands such as `get_link`. It makes a request to the backend server for the data, but any other requests coming in while the first is pending also get the responses from the first one.
func C2SHandleRemoteCommand ¶
func C2SHandleRemoteCommand(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
func C2SHello ¶
func C2SHello(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (_ ClientMessage, err error)
C2SHello implements the `hello` C2S Command. It calls SubscribeGlobal() and SubscribeDefaults() with the client, and fills out ClientInfo.Version and ClientInfo.ClientID.
func C2SPing ¶
func C2SPing(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
func C2SReady ¶
func C2SReady(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
func C2SSetUser ¶
func C2SSetUser(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
func C2SSubscribe ¶
func C2SSubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
func C2SSurvey ¶
func C2SSurvey(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
C2SSurvey implements the survey C2S Command.
func C2STrackFollow ¶
func C2STrackFollow(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (_ ClientMessage, err error)
C2STrackFollow implements the `track_follow` C2S Command. It adds the record to `followEvents`, which is submitted to the backend on a timer.
func C2SUnsubscribe ¶
func C2SUnsubscribe(_ *websocket.Conn, client *ClientInfo, msg ClientMessage) (ClientMessage, error)
C2SUnsubscribe implements the `unsub` C2S Command. It removes the channel from ClientInfo.CurrentChannels and calls UnsubscribeSingleChat.
func (*ClientMessage) ArgumentsAsInt ¶
func (cm *ClientMessage) ArgumentsAsInt() (int1 int64, err error)
ArgumentsAsInt parses the arguments of the ClientMessage as a single int.
func (*ClientMessage) ArgumentsAsString ¶
func (cm *ClientMessage) ArgumentsAsString() (string1 string, err error)
ArgumentsAsString parses the arguments of the ClientMessage as a single string.
func (*ClientMessage) ArgumentsAsStringAndBool ¶
func (cm *ClientMessage) ArgumentsAsStringAndBool() (str string, flag bool, err error)
ArgumentsAsStringAndBool parses the arguments of the ClientMessage as an array of a string and an int.
func (*ClientMessage) ArgumentsAsStringAndInt ¶
func (cm *ClientMessage) ArgumentsAsStringAndInt() (string1 string, int int64, err error)
ArgumentsAsStringAndInt parses the arguments of the ClientMessage as an array of a string and an int.
func (*ClientMessage) ArgumentsAsTwoStrings ¶
func (cm *ClientMessage) ArgumentsAsTwoStrings() (string1, string2 string, err error)
ArgumentsAsTwoStrings parses the arguments of the ClientMessage as an array of two strings.
func (ClientMessage) Reply ¶
func (cm ClientMessage) Reply(cmd Command, args interface{}) ClientMessage
func (ClientMessage) ReplyJSON ¶
func (cm ClientMessage) ReplyJSON(cmd Command, argsJSON string) ClientMessage
type ClientVersion ¶
func VersionFromString ¶
func VersionFromString(v string) ClientVersion
func (*ClientVersion) After ¶
func (cv *ClientVersion) After(cv2 *ClientVersion) bool
func (*ClientVersion) Equal ¶
func (cv *ClientVersion) Equal(cv2 *ClientVersion) bool
type Command ¶
type Command string
Command is a string indicating which RPC is requested. The Commands sent from Client -> Server and Server -> Client are disjoint sets.
const AsyncResponseCommand Command = "_async"
AsyncResponseCommand is a pseudo-Reply Command. It indicates that the Reply Command to the client's C2S Command will be delivered on a goroutine over the ClientInfo.MessageChannel and should not be delivered immediately.
const AuthorizeCommand Command = "do_authorize"
AuthorizeCommand is a S2C Command sent as part of Twitch username validation.
const ErrorCommand Command = "error"
ErrorCommand is a Reply Command to indicate that a C2S Command failed.
const HelloCommand Command = "hello"
HelloCommand is a C2S Command. HelloCommand must be the Command of the first ClientMessage sent during a connection. Sending any other command will result in a CloseFirstMessageNotHello.
const ReadyCommand Command = "ready"
ReadyCommand is a C2S Command. It indicates that the client is finished sending the initial 'sub' commands and the server should send the backlog.
const SetUserCommand Command = "setuser"
const SuccessCommand Command = "ok"
SuccessCommand is a Reply Command to indicate success in reply to a C2S Command.
type CommandHandler ¶
type CommandHandler func(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
CommandHandler is a RPC handler associated with a Command.
type ConfigFile ¶
type ConfigFile struct { // Numeric server id known to the backend ServerID int // Address to bind the HTTP server to on startup. ListenAddr string // Address to bind the TLS server to on startup. SSLListenAddr string // URL to the backend server BackendURL string // Minimum memory to accept a new connection MinMemoryKBytes uint64 // Maximum # of clients that can be connected. 0 to disable. MaxClientCount uint64 // SSL/TLS // Enable the use of SSL. UseSSL bool // Path to certificate file. SSLCertificateFile string // Path to key file. SSLKeyFile string // Origin Checking UseOriginChecks bool // Allowed Origins AllowedOrigins []string // Nacl keys OurPrivateKey []byte OurPublicKey []byte BackendPublicKey []byte // Request username validation from all new clients. SendAuthToNewClients bool // Proxy Routes ProxyRoutes []ProxyRoute }
var Configuration *ConfigFile
Configuration is the active ConfigFile.
type ErrBackendNotOK ¶
ErrBackendNotOK indicates that the backend replied with something other than the string "ok".
func (ErrBackendNotOK) Error ¶
func (noe ErrBackendNotOK) Error() string
Error Implements the error interface.
type ErrForwardedFromBackend ¶
type ErrForwardedFromBackend struct {
JSONError interface{}
}
ErrForwardedFromBackend is an error returned by the backend server.
func (ErrForwardedFromBackend) Error ¶
func (bfe ErrForwardedFromBackend) Error() string
type LastSavedMessage ¶
LastSavedMessage contains a reply to a command along with an expiration time.
type PendingAuthorization ¶
type PendingAuthorization struct { Client *ClientInfo Challenge string Callback AuthCallback EnteredAt time.Time }
type PeriodUniqueUsers ¶
type PeriodUniqueUsers struct { Start time.Time End time.Time Counter *hyperloglog.HyperLogLogPlus }
type ProxyRoute ¶
type StatsData ¶
type StatsData struct { StatsDataVersion int StartTime time.Time Uptime string BuildTime string BuildHash string CachedStatsLastUpdate time.Time Health struct { IRC bool Backend map[string]time.Time } CurrentClientCount uint64 LiveClientCount uint64 PubSubChannelCount int SysMemTotalKB uint64 SysMemFreeKB uint64 MemoryInUseKB uint64 MemoryRSSKB uint64 ResponseCacheItems int MemPerClientBytes uint64 CpuUsagePct float64 ClientConnectsTotal uint64 ClientDisconnectsTotal uint64 ClientVersions map[string]uint64 DisconnectCodes map[string]uint64 CommandsIssuedTotal uint64 CommandsIssuedMap map[Command]uint64 MessagesSent uint64 EmotesReportedTotal uint64 BackendVerifyFails uint64 // DisconnectReasons is at the bottom because it has indeterminate size DisconnectReasons map[string]uint64 // contains filtered or unexported fields }
type StringPool ¶
var CommandPool *StringPool
var PubSubChannelPool *StringPool
var TwitchChannelPool *StringPool
func NewStringPool ¶
func NewStringPool() *StringPool
func (*StringPool) Intern ¶
func (p *StringPool) Intern(s string) string
func (*StringPool) InternCommand ¶
func (p *StringPool) InternCommand(s string) Command
type SubscriberList ¶
type SubscriberList struct { sync.RWMutex Members []*ClientInfo }