# 15.11 与 websocket 通信

备注：Go 团队决定从 Go 1 起，将 `websocket`  包移出 Go 标准库，转移到 `code.google.com/p/go` 下的子项目 `websocket`，同时预计近期将做重大更改。

`import "websocket"` 这行要改成：
```go
import websocket "code.google.com/p/go/websocket"
```

与 http 协议相反，websocket 是通过客户端与服务器之间的对话，建立的基于单个持久连接的协议。然而在其他方面，其功能几乎与 http 相同。在示例 15.24 中，我们有一个典型的 websocket 服务器，他会自启动并监听 websocket 客户端的连入。示例 15.25 演示了 5 秒后会终止的客户端代码。当连接到来时，服务器先打印 `new connection`，当客户端停止时，服务器打印 `EOF => closing connection`。

示例 15.24 [websocket_server.go](examples/chapter_15/websocket_server.go)
```go
package main

import (
	"fmt"
	"net/http"
	"websocket"
)

func server(ws *websocket.Conn) {
	fmt.Printf("new connection\n")
	buf := make([]byte, 100)
	for {
		if _, err := ws.Read(buf); err != nil {
			fmt.Printf("%s", err.Error())
			break
		}
	}
	fmt.Printf(" => closing connection\n")
	ws.Close()
}

func main() {
	http.Handle("/websocket", websocket.Handler(server))
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}
```

示例 15.25 [websocket_client.go](examples/chapter_15/websocket_client.go)
```go
package main

import (
	"fmt"
	"time"
	"websocket"
)

func main() {
	ws, err := websocket.Dial("ws://localhost:12345/websocket", "",
		"http://localhost/")
	if err != nil {
		panic("Dial: " + err.Error())
	}
	go readFromServer(ws)
	time.Sleep(5e9)
    ws.Close()
}

func readFromServer(ws *websocket.Conn) {
	buf := make([]byte, 1000)
	for {
		if _, err := ws.Read(buf); err != nil {
			fmt.Printf("%s\n", err.Error())
			break
		}
	}
}
```

## 链接

- [目录](directory.md)
- 上一节：[基于网络的通道 netchan](15.10.md)
- 下一节：[用 smtp 发送邮件](15.12.md)
