本文环境基于centOS6.5

安装go1.8

下载go安装包,解压到/usr/local/,

cd /usr/local/src
wget http://golangtc.com/static/go/1.8/go1.8.linux-amd64.tar.gz
tar -zxvf go1.8.linux-amd64.tar.gz
mv go ../

设置环境变量,GOROOT和GOPATH

GOROOT就是go的安装路径

GOPATH
go install/go get和 go的工具等会用到GOPATH环境变量.
GOPATH是作为编译后二进制的存放目的地和import包时的搜索路径 (其实也是你的工作目录, 你可以在src下创建你自己的go源文件, 然后开始工作)。
GOPATH之下主要包含三个目录: bin、pkg、src
bin目录主要存放可执行文件; pkg目录存放编译好的库文件, 主要是*.a文件; src目录下主要存放go的源文件
不要把GOPATH设置成go的安装路径,

GOPATH可以是一个目录列表, go get下载的第三方库, 一般都会下载到列表的第一个目录里面
需要把GOPATH中的可执行目录也配置到环境变量中, 否则你自行下载的第三方go工具就无法使用了, 操作如下:
export $PATH:$GOPATH/bin

在/var/下新建go-project作为工作目录,

综合以上,做如下操作:

vi /etc/profile

GOROOT=/usr/local/go

export GOROOT

PATH=$PATH:$GOROOT/bin

GOPATH=/var/go-project

PATH=$PATH:$GOPATH/bin

export PATH

source /etc/profile
go version
go version go1.8 linux/amd64

测试是否安装成功

新建一个hello.go文件

package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

通过 go 工具运行它

go run hello.go
hello, world

看到了“hello, world”信息,那么Go已被正确安装。

下载官方websocket包

使用的golang官方的net包下面的websocket,地址:
https://github.com/golang/net

go get github.com/golang/net

其中有一些注意事项:

Golang 官方的子仓库,应该使用 import "golang.org/x/net/websocket" 这种方式导入,通过 go
get 方式下载。如果使用 git clone,clone下来的目录,也应该使用
src/golang.org/x/net/websocket 这样的目录,所以做法就特别蛋疼

要先

go get github.com/golang/net/websocket

然后

mv github.com/golang/net/websocket golang.org/x/net/websocket

然后import的时候用 golang.org/x/net/websocket

特别的蛋疼,难道是不想人用github上面的?因为上面的不是稳定版本

于是,将/var/go-project/src/github.com/golang/net重命名成了/var/go-project/src/golang.org/x/net

然后,go install golang.org/x/net/websocket

简单实现websocket广播的server端代码(server.go):

package main
import (
    "golang.org/x/net/websocket"
    "fmt"
    "log"
    "net/http"
)

var (  
    JSON          = websocket.JSON              // codec for JSON  
    Message       = websocket.Message           // codec for string, []byte  
    ActiveClients = make(map[ClientConn]string) // map containing clients  
    User          = make(map[string]string)  
)  

type ClientConn struct {  
    websocket *websocket.Conn  
    clientIP string  
}

func echoHandler(ws *websocket.Conn) {
    var err error  
    for {  
        var reply string  
        if err = websocket.Message.Receive(ws, &reply); err != nil {  
            fmt.Println("can't receive")  
            break  
        }  

        client := ws.Request().RemoteAddr  
        fmt.Println("Client connected:", client) 

        sockCli := ClientConn{ws, client}  
        ActiveClients[sockCli] = client 
        fmt.Println("Number of clients connected:", len(ActiveClients))

        if ActiveClients[sockCli] != "" {  
            for cs, na := range ActiveClients {  
                if na != "" {  
                    if err = websocket.Message.Send(cs.websocket, reply); err != nil {  
                        log.Println("Could not send message to ", cs.clientIP, err.Error())  
                    }  
                }  
            }  
        }
    }  

}

func main() {
    http.Handle("/echo", websocket.Handler(echoHandler))
    http.Handle("/", http.FileServer(http.Dir(".")))

    err := http.ListenAndServe(":8080", nil)

    if err != nil {
        panic("ListenAndServe: " + err.Error())
    }
}

运行服务端代码

go run server.go

客户端html代码,置于nginx下,通过域名访问,打开两个浏览器,可以实现简单聊天功能

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>Sample of websocket with golang</title>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <script>
      $(function() {
        var ws = new WebSocket("ws://xxx.xx.xxx.xx:8080/echo");
        ws.onmessage = function(e) {
          $('<li>').text(event.data).appendTo($ul);
        };
        var $ul = $('#msg-list');
        $('#sendBtn').click(function(){
          var data = $('#name').val();
          ws.send(data);
        });
      });
    </script>
</head>
<body>
<input id="name" type="text"/>
<input type="button" id="sendBtn" value="send"/>
<ul id="msg-list"></ul>
</body>
</html>