2.2 实现 Server v0.1

// server/main.go
package main

import (
    "fmt"
    "net"

    "github.com/huoyijie/GoChat/lib"
)

func main() {
    // 启动单独协程,监听 ctrl+c 或 kill 信号,收到信号结束进程
    go lib.SignalHandler()

    // tcp 监听地址 0.0.0.0:8888
    addr := ":8888"

    // tcp 监听
    ln, err := net.Listen("tcp", addr)

    // tcp 监听遇到错误退出进程
    lib.FatalNotNil(err)
    // 输出日志
    lib.LogMessage("Listening on", addr)

    // 循环接受客户端连接
    for {
        // 每当有客户端连接时,ln.Accept 会返回新的连接 conn
        conn, err := ln.Accept()
        // 如果接受的新连接遇到错误,则退出进程
        lib.FatalNotNil(err)

        // 通过 conn 向连接的另一侧发送消息
        fmt.Fprintf(conn, "Hello, World!\r\n")

        // 为每个新连接启动一个单独协程,该协程会读取另一侧发送的消息
        go lib.HandleConnection(conn)
    }
}

关键字 go 会开启一个协程 (goroutine),协程是由 Go 运行时管理的轻量级线程。上面的程序有两处使用了协程。

// 1.启动信号监听协程
go lib.SignalHandler()
// 2.启动连接处理协程
go lib.HandleConnection(conn)

关于协程的概念可以看 Effective Go: Goroutines

协程的示例程序可以看 Tour: GoroutinesGo by Example: Goroutines