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 上,并处理客户端连接和消息处理。客户端连接到服务器并定期发送消息。服务器接收消息并将其广播给所有已连接的客户端。

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

相关推荐
希望20172 小时前
Golang Panic & Throw & Map/Channel 并发笔记
开发语言·golang
朗迹 - 张伟2 小时前
Golang安装笔记
开发语言·笔记·golang
橙*^O^*安4 小时前
Go 语言基础:变量与常量
运维·开发语言·后端·golang·kubernetes
工程师小星星4 小时前
Golang语言的文件组织方式
开发语言·后端·golang
qq_172805598 小时前
GO RPC 教学文档
qt·rpc·golang
蒋星熠12 小时前
WebSocket网络编程深度实践:从协议原理到生产级应用
网络·数据库·redis·python·websocket·网络协议·微服务
catchadmin16 小时前
开发 PHP 扩展新途径 通过 FrankenPHP 用 Go 语言编写 PHP 扩展
android·golang·php
午夜游鱼17 小时前
Go 泛型实战:一行代码封装 sync.Pool,性能与安全兼得
开发语言·安全·golang
MetaverseMan20 小时前
Golang单例模式和工厂模式详解
开发语言·golang·适配器模式
kite01211 天前
Gin + Zap 日志:构建高性能、结构化的应用日志系统
golang·gin·log·zap