3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-02 00:49:25 +01:00

idle/quit timeout

This commit is contained in:
Jeremy Latt 2014-02-09 12:13:09 -08:00
parent 8a90634c0a
commit 133b91b9f0
4 changed files with 47 additions and 8 deletions

View File

@ -8,7 +8,6 @@ import (
) )
type Client struct { type Client struct {
atime time.Time
away bool away bool
channels ChannelSet channels ChannelSet
conn net.Conn conn net.Conn
@ -22,6 +21,8 @@ type Client struct {
server *Server server *Server
serverPass bool serverPass bool
username string username string
idleTimer *time.Timer
quitTimer *time.Timer
} }
func NewClient(server *Server, conn net.Conn) *Client { func NewClient(server *Server, conn net.Conn) *Client {
@ -40,9 +41,38 @@ func NewClient(server *Server, conn net.Conn) *Client {
go client.readConn(read) go client.readConn(read)
go client.writeConn(write, replies) go client.writeConn(write, replies)
client.Touch()
return client return client
} }
func (client *Client) Touch() {
if client.quitTimer != nil {
client.quitTimer.Stop()
}
if client.idleTimer == nil {
client.idleTimer = time.AfterFunc(IDLE_TIMEOUT, client.Idle)
} else {
client.idleTimer.Reset(IDLE_TIMEOUT)
}
}
func (client *Client) Idle() {
if client.quitTimer == nil {
client.quitTimer = time.AfterFunc(QUIT_TIMEOUT, client.Quit)
} else {
client.quitTimer.Reset(QUIT_TIMEOUT)
}
client.Reply(RplPing(client.server, client))
}
func (client *Client) Quit() {
msg := &QuitCommand{
message: "connection timeout",
}
msg.SetClient(client)
client.server.commands <- msg
}
func (c *Client) readConn(recv <-chan string) { func (c *Client) readConn(recv <-chan string) {
for str := range recv { for str := range recv {
m, err := ParseCommand(str) m, err := ParseCommand(str)

View File

@ -2,6 +2,7 @@ package irc
import ( import (
"errors" "errors"
"time"
) )
var ( var (
@ -16,6 +17,12 @@ var (
const ( const (
VERSION = "ergonomadic-1" VERSION = "ergonomadic-1"
CRLF = "\r\n" CRLF = "\r\n"
MAX_REPLY_LEN = 512 - len(CRLF)
// how long before a client is considered idle
IDLE_TIMEOUT = time.Minute
// how long after idle before a client is kicked
QUIT_TIMEOUT = time.Minute
// numeric codes // numeric codes
RPL_WELCOME = 1 RPL_WELCOME = 1
@ -161,6 +168,7 @@ const (
RPL_JOIN = "JOIN" RPL_JOIN = "JOIN"
RPL_NICK = "NICK" RPL_NICK = "NICK"
RPL_PART = "PART" RPL_PART = "PART"
RPL_PING = "PING"
RPL_PONG = "PONG" RPL_PONG = "PONG"
RPL_PRIVMSG = "PRIVMSG" RPL_PRIVMSG = "PRIVMSG"
RPL_QUIT = "QUIT" RPL_QUIT = "QUIT"

View File

@ -6,10 +6,6 @@ import (
"time" "time"
) )
const (
MAX_REPLY_LEN = 510 // 512 - CRLF
)
func joinedLen(names []string) int { func joinedLen(names []string) int {
var l = len(names) - 1 // " " between names var l = len(names) - 1 // " " between names
for _, name := range names { for _, name := range names {
@ -139,6 +135,10 @@ func RplPart(client *Client, channel *Channel, message string) Reply {
return NewStringReply(client, RPL_PART, "%s :%s", channel.name, message) return NewStringReply(client, RPL_PART, "%s :%s", channel.name, message)
} }
func RplPing(server *Server, target Identifier) Reply {
return NewStringReply(server, RPL_PING, target.Nick())
}
func RplPong(server *Server, client *Client) Reply { func RplPong(server *Server, client *Client) Reply {
return NewStringReply(server, RPL_PONG, client.Nick()) return NewStringReply(server, RPL_PONG, client.Nick())
} }

View File

@ -47,7 +47,8 @@ func (server *Server) receiveCommands(commands <-chan Command) {
log.Printf("%s → %s : %s", command.Client(), server, command) log.Printf("%s → %s : %s", command.Client(), server, command)
} }
client := command.Client() client := command.Client()
client.atime = time.Now() client.Touch()
if !client.serverPass { if !client.serverPass {
if server.password == "" { if server.password == "" {
client.serverPass = true client.serverPass = true