Golang 中实现实时聊天通讯

客户端代码

go 复制代码
package main

import (
    "fmt"
    "log"
    "net/url"
    "os"
    "os/signal"
    "time"

    "github.com/gorilla/websocket"
)

func main() {
    interrupt := make(chan os.Signal, 1)
    signal.Notify(interrupt, os.Interrupt)

    u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/chat"}
    log.Printf("connecting to %s", u.String())

    c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    if err != nil {
        log.Fatal("dial:", err)
    }
    defer c.Close()

    done := make(chan struct{})

    go func() {
        defer close(done)
        for {
            _, message, err := c.ReadMessage()
            if err != nil {
                log.Println("read:", err)
                return
            }
            log.Printf("received: %s", message)
        }
    }()

    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-done:
            return
        case t := <-ticker.C:
            err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
            if err != nil {
                log.Println("write:", err)
                return
            }
        case <-interrupt:
            log.Println("interrupt")
            err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
            if err != nil {
                log.Println("write close:", err)
                return
            }
            select {
            case <-done:
            case <-time.After(time.Second):
            }
            return
        }
    }
}

服务器端代码

go 复制代码
package main

import (
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var clients = make(map[*websocket.Conn]bool) 
var broadcast = make(chan Message)            

type Message struct {
    Username string `json:"username"`
    Message  string `json:"message"`
}

func main() {
    http.HandleFunc("/chat", handleConnections)
    go handleMessages()
    log.Println("Server started on localhost:8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    upgrader := websocket.Upgrader{}
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer ws.Close()

    clients[ws] = true

    for {
        var msg Message
        err := ws.ReadJSON(&msg)
        if err != nil {
            log.Printf(": %v", err)
            delete(clients, ws)
            break
        }
        broadcast <- msg
    }
}

func handleMessages() {
    for {
        msg := <-broadcast
        for client := range clients {
            err := client.WriteJSON(msg)
            if err != nil {
                log.Printf(": %v", err)
                client.Close()
                delete(clients, client)
            }
        }
    }
}

以上代码创建了一个简单的聊天服务器和一个聊天客户端,通过 WebSocket 进行实时通信。服务器监听在 localhost:8080 上,并处理客户端连接和消息处理。客户端连接到服务器并定期发送消息。服务器接收消息并将其广播给所有已连接的客户端。

可以根据具体需求进行更多的定制和扩展。

相关推荐
艾莉丝努力练剑18 分钟前
【AI大模型接入SDK】ChatGPT API
网络·c++·人工智能·websocket·网络协议·学习·chatgpt
wjcroom12 小时前
一个可以在线多人玩的五子棋开发与布署方法-WebRTC和WebSocket的测试方法
websocket·网络协议·webrtc
平头哥AI15 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
2601_9622965116 小时前
如何使用Golang包路径_管理本地和远程模块引用
golang·数据转换·变量定义·常用库·编程语言区别
FfHUCisI21 小时前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
我不会起名字32221 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·
gsls2008081 天前
告别 Vault 的复杂度:用 Go 标准库给 Windows 凭据管理器装上 MCP
windows·golang·mcp
名字还没想好☜1 天前
Go 时间格式化为什么用 2006-01-02:time.Format/Parse 的参考时间、时区与解析踩坑
开发语言·后端·golang·go
Sylvia33.1 天前
LOL实时数据接入深度解析:从WebSocket到完整数据模型
java·网络·python·websocket·网络协议
FfHUCisI2 天前
Golang Map 哈希表实现
golang·哈希算法·散列表