Go实战--golang中使用WebSocket实时聊天室 gorilla/websocket nkovacs/go-s

                       

生命不止,继续 go go go!!!

其实,早就应该跟大家分享golang中关于websocket的使用,但是一直不知道从何入手,也不能够很清晰的描述出来。

今天就浅尝辄止,通过第三方库实现websocket。

WebSocket

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。

WebSocket协议支持(在受控环境中运行不受信任的代码的)客户端与(选择加入该代码的通信的)远程主机之间进行全双工通信。用于此的安全模型是Web浏览器常用的基于原始的安全模式。 协议包括一个开放的握手以及随后的TCP层上的消息帧。 该技术的目标是为基于浏览器的、需要和服务器进行双向通信的(服务器不能依赖于打开多个HTTP连接(例如,使用XMLHttpRequest或iframe和长轮询))应用程序提供一种通信机制。

这里写图片描述

gorilla/websocket

A WebSocket implementation for Go.

github地址:
https://github.com/gorilla/websocket

Star: 4307

获取:

go get github.com/gorilla/websocket
  
  
  
  • 1

Server

其中,用到了satori/go.uuid:
Go实战–golang生成uuid(The way to go)

server.go

package mainimport (    "encoding/json"    "fmt"    "net/http"    "github.com/gorilla/websocket"    "github.com/satori/go.uuid")type ClientManager struct {    clients    map[*Client]bool    broadcast  chan []byte    register   chan *Client    unregister chan *Client}type Client struct {    id     string    socket *websocket.Conn    send   chan []byte}type Message struct {    Sender    string `json:"sender,omitempty"`    Recipient string `json:"recipient,omitempty"`    Content   string `json:"content,omitempty"`}var manager = ClientManager{    broadcast:  make(chan []byte),    register:   make(chan *Client),    unregister: make(chan *Client),    clients:    make(map[*Client]bool),}func (manager *ClientManager) start() {    for {        select {        case conn := <-manager.register:            manager.clients[conn] = true            jsonMessage, _ := json.Marshal(&Message{Content: "/A new socket has connected."})            manager.send(jsonMessage, conn)        case conn := <-manager.unregister:            if _, ok := manager.clients[conn]; ok {                close(conn.send)                delete(manager.clients, conn)                jsonMessage, _ := json.Marshal(&Message{Content: "/A socket has disconnected."})                manager.send(jsonMessage, conn)            }        case message := <-manager.broadcast:            for conn := range manager.clients {                select {                case conn.send <- message:                default:                    close(conn.send)                    delete(manager.clients, conn)                }            }        }    }}func (manager *ClientManager) send(message []byte, ignore *Client) {    for conn := range manager.clients {        if conn != ignore {            conn.send <- message        }    }}func (c *Client) read() {    defer func() {        manager.unregister <- c        c.socket.Close()    }()    for {        _, message, err := c.socket.ReadMessage()        if err != nil {            manager.unregister <- c            c.socket.Close()            break        }        jsonMessage, _ := json.Marshal(&Message{Sender: c.id, Content: string(message)})        manager.broadcast <- jsonMessage    }}func (c *Client) write() {    defer func() {        c.socket.Close()    }()    for {        select {        case message, ok := <-c.send:            if !ok {                c.socket.WriteMessage(websocket.CloseMessage, []byte{})                return            }            c.socket.WriteMessage(websocket.TextMessage, message)        }    }}func main() {    fmt.Println("Starting application...")    go manager.start()    http.HandleFunc("/ws", wsPage)    http.ListenAndServe(":12345", nil)}func wsPage(res http.ResponseWriter, req *http.Request) {    conn, error := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(res, req, nil)    if error != nil {        http.NotFound(res, req)        return    }    client := &Client{id: uuid.NewV4().String(), socket: conn, send: make(chan []byte)}    manager.register <- client    go client.read()    go client.write()}
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129

Go Client

package mainimport (    "flag"    "fmt"    "net/url"    "time"    "github.com/gorilla/websocket")var addr = flag.String("addr", "localhost:12345", "http service address")func main() {    u := url.URL{Scheme: "ws", Host: *addr, Path: "/ws"}    var dialer *websocket.Dialer    conn, _, err := dialer.Dial(u.String(), nil)    if err != nil {        fmt.Println(err)        return    }    go timeWriter(conn)    for {        _, message, err := conn.ReadMessage()        if err != nil {            fmt.Println("read:", err)            return        }        fmt.Printf("received: %s\n", me
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在最新版本的 Go ,`golang.org/x/net/websocket` 包已经被废弃,推荐使用官方提供的 `github.com/gorilla/websocket` 包来处理 WebSocket 连接。以下是一个简单示例,演示如何使用 `github.com/gorilla/websocket` 包进行 WebSocket 通信: ```go package main import ( "log" "net/http" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } func main() { http.HandleFunc("/ws", handleWebSocket) log.Fatal(http.ListenAndServe(":8080", nil)) } func handleWebSocket(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("WebSocket 连接升级失败:", err) return } defer conn.Close() for { // 读取消息 _, msg, err := conn.ReadMessage() if err != nil { log.Println("WebSocket 读取消息失败:", err) break } log.Printf("收到 WebSocket 消息:%s\n", msg) // 处理消息 // ... // 发送响应 err = conn.WriteMessage(websocket.TextMessage, []byte("收到消息")) if err != nil { log.Println("WebSocket 发送响应失败:", err) break } } } ``` 在上述示例,我们首先创建了一个 `websocket.Upgrader` 对象,并设置了其的 `CheckOrigin` 函数以允许跨域请求。然后我们定义了一个 `handleWebSocket` 函数,用于处理 WebSocket 连接。 在 `handleWebSocket` 函数,我们通过 `upgrader.Upgrade` 方法将 HTTP 连接升级为 WebSocket 连接。然后,我们进入一个循环来处理收到的消息。您可以在循环添加您自己的消息处理逻辑,并通过 `conn.WriteMessage` 方法发送响应。 请注意,这只是一个简单的示例,您可能需要根据您的实际需求进行适当的配置和错误处理。 希望以上信息对您有所帮助!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值