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

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

相关推荐
Generalzy4 小时前
从本地 Demo 到生产级检索:Milvus 学习笔记(2)
golang·milvus
张3238 小时前
Go语言基础 Map 函数值 闭包
开发语言·golang
北冥you鱼9 小时前
Go Modules 使用指南:从入门到精通
开发语言·后端·golang
灯澜忆梦10 小时前
【dp_1】爬楼梯 | 斐波那契数 | 第 N 个泰波那契数 | 三步问题
算法·golang
永久鳕10 小时前
WebSocket 连接成功但行情不更新,应该先查哪几个状态?
网络·websocket·网络协议
geovindu10 小时前
go: Floyd-Warshall Algorithms
开发语言·后端·算法·golang
JerrySir1 天前
Node.js WebSocket 优雅关闭:一次滚动发布如何避免 1 万次重连风暴
websocket
CryptoPP1 天前
BSE股票K线数据接入实战:从接口调用到前端图表展示
大数据·前端·网络·人工智能·websocket·网络协议
宠友信息1 天前
多端即时通讯源码技术实践,Redis路由、MySQL持久化与Socket接入
spring boot·websocket·mysql·uni-app
大侠锅锅1 天前
第 9 篇:状态机实践——状态环 + 步进表替代 if-else 地狱
golang·边缘计算·状态机