ch8: fix code format

This commit is contained in:
chai2010
2016-01-21 10:39:06 +08:00
parent 0b5ec941ed
commit b1730821fe
13 changed files with 393 additions and 404 deletions

View File

@@ -1,24 +1,25 @@
## 8.10. 示例: 聊天服務
我們用一個聊天服務器來終結本章節的內容這個程序可以讓一些用戶通過服務器向其它所有用戶廣播文本消息。這個程序中有四種goroutine。main和broadcaster各自是一個goroutine實例每一個客戶端的連接都會有一個handleConn和clientWriter的goroutine。broadcaster是select用法的不錯的樣例因爲它需要處理三種不同類型的消息。
下面演示的main goroutine的工作是listen和accept(譯註:網絡編程里的概念)從客戶端過來的連接。對每一個連接程序都會建立一個新的handleConn的goroutine就像我們在本章開頭的併發的echo服務器里所做的那樣。
<u><i>gopl.io/ch8/chat</i></u>
```go
gopl.io/ch8/chat
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
go broadcaster()
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
go broadcaster()
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
}
```
@@ -28,29 +29,29 @@ func main() {
type client chan<- string // an outgoing message channel
var (
entering = make(chan client)
leaving = make(chan client)
messages = make(chan string) // all incoming client messages
entering = make(chan client)
leaving = make(chan client)
messages = make(chan string) // all incoming client messages
)
func broadcaster() {
clients := make(map[client]bool) // all connected clients
for {
select {
case msg := <-messages:
// Broadcast incoming message to all
// clients' outgoing message channels.
for cli := range clients {
cli <- msg
}
case cli := <-entering:
clients[cli] = true
clients := make(map[client]bool) // all connected clients
for {
select {
case msg := <-messages:
// Broadcast incoming message to all
// clients' outgoing message channels.
for cli := range clients {
cli <- msg
}
case cli := <-entering:
clients[cli] = true
case cli := <-leaving:
delete(clients, cli)
close(cli)
}
}
case cli := <-leaving:
delete(clients, cli)
close(cli)
}
}
}
```
@@ -60,29 +61,29 @@ broadcaster監聽來自全局的entering和leaving的channel來獲知客戶端
```go
func handleConn(conn net.Conn) {
ch := make(chan string) // outgoing client messages
go clientWriter(conn, ch)
ch := make(chan string) // outgoing client messages
go clientWriter(conn, ch)
who := conn.RemoteAddr().String()
ch <- "You are " + who
messages <- who + " has arrived"
entering <- ch
who := conn.RemoteAddr().String()
ch <- "You are " + who
messages <- who + " has arrived"
entering <- ch
input := bufio.NewScanner(conn)
for input.Scan() {
messages <- who + ": " + input.Text()
}
// NOTE: ignoring potential errors from input.Err()
input := bufio.NewScanner(conn)
for input.Scan() {
messages <- who + ": " + input.Text()
}
// NOTE: ignoring potential errors from input.Err()
leaving <- ch
messages <- who + " has left"
conn.Close()
leaving <- ch
messages <- who + " has left"
conn.Close()
}
func clientWriter(conn net.Conn, ch <-chan string) {
for msg := range ch {
fmt.Fprintln(conn, msg) // NOTE: ignoring network errors
}
for msg := range ch {
fmt.Fprintln(conn, msg) // NOTE: ignoring network errors
}
}
```