diff --git a/README.md b/README.md index a5764de..96387cb 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Rudimentary go chat server as a fun project. ```bash git clone https://git.coolaj86.com/coolaj86/chat.go.git +go get gopkg.in/yaml.v2 ``` # Usage diff --git a/chatserver.go b/chatserver.go index 1b118ea..e12c466 100644 --- a/chatserver.go +++ b/chatserver.go @@ -8,13 +8,24 @@ import ( "flag" "fmt" "io" + "io/ioutil" "net" "os" "strconv" "sync" "time" + + "gopkg.in/yaml.v2" ) +type Conf struct { + Port uint `yaml:"port,omitempty"` + Mailer struct { + ApiKey string `yaml:"api_key,omitempty"` + From string `yaml:"from,omitempty"` + } +} + type bufferedConn struct { r *bufio.Reader rout io.Reader @@ -61,6 +72,13 @@ func usage() { } func handleRaw(conn bufferedConn) { + // TODO + // What happens if this is being read from range + // when it's being added here (data race)? + // Should I use a channel here instead? + // TODO see https://jameshfisher.com/2017/04/18/golang-tcp-server.html + myRawConns[conn] = true + // Handle all subsequent packets buf := make([]byte, 1024) for { @@ -179,16 +197,35 @@ func handleConnection(conn net.Conn) { } func main() { + flag.Usage = usage + port := flag.Uint("telnet-port", 0, "tcp telnet chat port") + confname := flag.String("config", "./config.yml", "ymal config file") + flag.Parse() + + var config Conf + confstr, err := ioutil.ReadFile(*confname) + fmt.Fprintf(os.Stdout, "-config=%s\n", *confname) + if nil != err { + fmt.Fprintf(os.Stderr, "%s\nUsing defaults instead\n", err) + confstr = []byte("{\"port\":" + strconv.Itoa(int(*port)) + "}") + } + err = yaml.Unmarshal(confstr, &config) + if nil != err { + config = Conf{} + } + firstMsgs = make(chan myMsg, 128) myMsgs = make(chan myMsg, 128) newConns = make(chan net.Conn, 128) myRawConns = make(map[net.Conn]bool) myUnsortedConns = make(map[net.Conn]bool) - flag.Usage = usage - port:= flag.Uint("telnet-port", 4080, "tcp telnet chat port") - flag.Parse() - addr := ":" + strconv.Itoa(int(*port)) + var addr string + if 0 != int(*port) { + addr = ":" + strconv.Itoa(int(*port)) + } else { + addr = ":" + strconv.Itoa(int(config.Port)) + } // https://golang.org/pkg/net/#Conn sock, err := net.Listen("tcp", addr) @@ -213,6 +250,8 @@ func main() { for { select { case conn := <- newConns: + ts := time.Now() + fmt.Fprintf(os.Stdout, "[Handle New Connection] [Timestamp] %s\n", ts) go handleConnection(conn) case msg := <- myMsgs: ts, err := msg.receivedAt.MarshalJSON() diff --git a/config.sample.yml b/config.sample.yml new file mode 100644 index 0000000..acd20c7 --- /dev/null +++ b/config.sample.yml @@ -0,0 +1,4 @@ +port: 4080 +mailer: + api_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + from: 'mailer@example.com'