Golang基于WebSocket实现简易聊天室:代码解析与运行指南

晚来风
晚来风
发布时间:2026-10-13| 4人浏览过
原创

本文分享了使用Golang实现简易WebSocket聊天室的完整过程。内容包含服务端的核心广播逻辑、前端网页客户端交互代码以及命令行测试工具,帮助开发者快速理解Websocket在Go语言中的双向通信应用。

实现目标与原理

本示例旨在展示如何利用Go语言标准库 net/http 配合第三方 websocket 包,建立一个支持多用户连接的实时聊天系统。核心机制包括:建立连接时分配唯一ID并广播欢迎信息;接收消息后遍历连接列表进行转发(排除发送者自身);断开连接时清理资源并通知其他用户。

环境准备

由于使用了早期版本的 websocket 实现,首先需要获取依赖包。在终端执行以下命令:

go get code.google.com/p/go.net/websocket

请确保网络通畅以拉取旧版仓库。若当前 Go 版本较高且无法访问该仓库,可考虑将 import 路径替换为社区维护的镜像(如 github.com/gorilla/websocket),但需注意后续代码中 API 的差异。

第1步:实现服务端核心逻辑

服务端负责监听端口、处理 HTTP 升级请求以及管理所有在线客户端。我们将聊天室的主要逻辑封装在 ChatroomServer 函数中。

1.1 连接管理与广播

服务端使用 container/list 维护所有活跃的 WebSocket 连接。当新连接进入时,生成 ID 并存入列表;消息广播时遍历该列表向所有客户端推送数据。

  • 目的:管理用户状态并实现群发功能。
  • 关键动作:
    - ChatroomServer 中调用 conns.PushBack(ws) 加入房间。
    - SendMessage 函数遍历链表,调用 io.WriteString 发送消息给除发送者外的所有节点。

1.2 启动服务

在 main 函数中注册路由:

  • /chatroom:映射到 websocket handler,用于实际通信。
  • /:返回静态 HTML 页面,提供浏览器入口。
  • 监听端口::6611。

第2步:浏览器客户端界面

为了方便测试,我们直接在服务端返回一个简单的 HTML/JS 页面。页面内置了 jQuery 和原生 WebSocket API。

关键参数说明:

  • 连接地址:ws://127.0.0.1:6611/chatroom。
  • 消息格式:输入文本后自动附加换行符 '\n' 发送给服务器。
  • UI 逻辑:收到消息后追加至 #log 区域并自动滚动到底部。
var ws = new WebSocket("ws://127.0.0.1:6611/chatroom");
// ... 省略事件监听 ...
ws.send($('#msg').val()+"\n");

第3步:命令行客户端测试

除了浏览器,我们可以编写一个简单的 Go 命令行程序来模拟另一个聊天气泡,验证双端通信。这有助于在不打开浏览器的情况下测试后台服务稳定性。

操作流程:

  1. 建立连接:使用 websocket.Dial 指定 URL 和 Origin。
  2. 并发读取:启动 Goroutine 读取标准输入,每行写入 WebSocket。
  3. 主循环接收:主循环持续从 WebSocket 读取服务端下发的消息。
origin := "http://127.0.0.1:6611/"
url := "ws://127.0.0.1:6611/chatroom"
ws, err := websocket.Dial(url, "", origin)

完整源码参考

以下是合并后的服务端代码及对应的 HTML 模板结构。请注意,此代码使用了较老的 code.google.com 包路径,仅作为学习 WebSocket 协议在 Golang 中实现逻辑的参考。

package main

import (
    "fmt"
    "io"
    "bufio"
    "net/http"
    "code.google.com/p/go.net/websocket"
    "container/list"
)

var connid int
var conns *list.List

func ChatroomServer(ws *websocket.Conn) {
    defer ws.Close()
    connid++
    id := connid
    fmt.Printf("connection id: %d\n", id)
    item := conns.PushBack(ws)
    defer conns.Remove(item)
    name := fmt.Sprintf("user%d", id)
    SendMessage(nil, fmt.Sprintf("welcome %s join\n", name))
    r := bufio.NewReader(ws)
    for {
        data, err := r.ReadBytes('\n')
        if err != nil {
            fmt.Printf("disconnected id: %d\n", id)
            SendMessage(item, fmt.Sprintf("%s offline\n", name))
            break
        }
        fmt.Printf("%s: %s", name, data)
        SendMessage(item, fmt.Sprintf("%s\t> %s", name, data))
    }
}

func SendMessage(self *list.Element, data string) {
    for item := conns.Front(); item != nil; item = item.Next() {
        ws, ok := item.Value.(*websocket.Conn)
        if !ok {
            panic("item not *websocket.Conn")
        }
        if item == self {
            continue
        }
        io.WriteString(ws, data)
    }
}

func Client(w http.ResponseWriter, r *http.Request) {
    html := `<!doctype html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>golang websocket chatroom</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>
        var ws = new WebSocket("ws://127.0.0.1:6611/chatroom");
        // ... (此处省略前端JS详细代码,见上文第2步说明) ...
    </script>
</head>
<body>
    <div id="log" style="height: 300px;overflow-y: scroll;border: 1px solid #CCC;"></div>
    <div>
        <form id="msgform">
            <input type="text" id="msg" size="60" />
        </form>
    </div>
</body>
</html>`
    io.WriteString(w, html)
}

func main() {
    fmt.Printf(`Welcome chatroom server!`)
    connid = 0
    conns = list.New()
    http.Handle("/chatroom", websocket.Handler(ChatroomServer));
    http.HandleFunc("/", Client);
    err := http.ListenAndServe(":6611", nil);
    if err != nil {
        panic("ListenAndServe: " + err.Error())
    }
}

运行与排错

  • 启动服务:运行编译后的二进制文件,终端应显示 Welcome chatroom server! 并无报错输出。
  • 访问测试:浏览器打开 http://127.0.0.1:6611,观察控制台是否触发 onopen 事件。
  • 跨域注意:原始代码中设置了固定的 Origin。如果在非 127.0.0.1:6611 下部署,需调整 Client 中 JS 的 WS URL 或服务端的 Origin 检查逻辑(注:原代码未显式拦截 Origin,依赖底层默认行为)。

以上就是Golang基于WebSocket实现的简易聊天室程序的详细内容,更多关于Golang WebSocket开发的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。