Golang实现一个聊天工具

2024-04-05 05:36
文章标签 实现 golang 聊天工具

本文主要是介绍Golang实现一个聊天工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

聊天工具作为实时通讯的必要工具,在现代互联网世界中扮演着重要的角色。本博客将指导如何使用 Golang 构建一个简单但功能完善的聊天工具,利用 WebSocket 技术实现即时通讯的功能。

项目源码

点击下载

为什么选择 Golang

Golang 是一种高效、简洁且并发性强的编程语言。其强大的并发模型和高效的性能使其成为构建高负载实时应用的理想选择。在本教程中,我们将利用 Golang 的优势来创建一个轻量级但高效的聊天工具。

目标

本教程旨在演示如何使用 Golang 和 WebSocket 技术构建一个简单的聊天工具。我们将详细介绍服务器端和客户端的实现过程,从而能够了解聊天工具的基本结构和实现原理。

技术栈

在本教程中,我们将详细介绍 WebSocket 技术,这是构建实时通讯应用的核心组件。同时,我们还将使用 Golang、HTML/CSS/JavaScript 和 Gorilla WebSocket 库来构建一个简单的聊天工具。

WebSocket

WebSocket 是一种在单个 TCP 连接上提供全双工通信的网络通信协议。它允许客户端和服务器之间进行实时、双向的通讯,从而实现了实时更新、即时通讯等功能。

WebSocket 的特点包括:

全双工通信:客户端和服务器可以同时发送和接收数据。
实时性:实时的双向通信,适用于即时聊天、实时数据更新等场景。
少量数据传输:相较于传统 HTTP 请求,WebSocket 传输的数据包含更少的开销,因为它不需要在每次通讯时都发送头部信息。

WebSocket 的工作原理:

  1. 握手阶段:客户端发起 HTTP 请求,请求升级为 WebSocket 协议。
  2. 建立连接:服务端接受请求,升级为 WebSocket 连接。
  3. 双向通信:建立连接后,客户端和服务端可以相互发送消息。

在本教程中,我们将使用 WebSocket 技术来建立客户端与服务器之间的连接,以实现实时聊天的功能。

其他技术

除了 WebSocket,我们还将使用以下技术来构建聊天工具:

Golang:作为后端语言,处理 WebSocket 连接,消息传递和处理。
HTML/CSS/JavaScript:创建简单的客户端界面,允许用户进行聊天。
Gorilla WebSocket 库:一个 Golang 的 WebSocket 库,提供了一些功能和工具,简化了使用 WebSocket 的过程。

构建服务器

在本节中,我们将开始构建聊天工具的服务器端,使用 Golang 和 Gorilla WebSocket 库来处理客户端的连接和消息传递。

设置基本结构

首先,我们需要创建 Golang 项目结构,确保安装了 Gorilla WebSocket 库。在项目中创建一个 main.go 文件,并导入 WebSocket 库。

package mainimport ("log""net/http""github.com/gorilla/websocket"
)var clients = make(map[*websocket.Conn]bool)
var broadcast = make(chan Message)
var upgrader = websocket.Upgrader{}type Message struct {Email    string `json:"email"`Username string `json:"username"`Message  string `json:"message"`
}

处理连接

接下来,我们将创建一个函数来处理客户端的连接。这个函数将升级 HTTP 连接为 WebSocket 连接,维护客户端连接池,并处理新消息的广播。

func handleConnections(w http.ResponseWriter, r *http.Request) {ws, err := upgrader.Upgrade(w, r, nil)if err != nil {log.Fatal(err)}defer ws.Close()clients[ws] = truefor {var msg Messageerr := ws.ReadJSON(&msg)if err != nil {log.Printf("error: %v", err)delete(clients, ws)break}broadcast <- msg}
}

处理消息广播

我们还需要一个函数来处理消息的广播,以便将消息传递给所有连接的客户端。

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

设置服务器

最后,我们需要设置服务器并启动监听。

func main() {http.HandleFunc("/ws", handleConnections)go handleMessages()log.Fatal(http.ListenAndServe(":8080", nil))
}

在本节中,我们建立了一个基本的服务器结构,使用 Golang 和 Gorilla WebSocket 库处理 WebSocket 连接和消息传递。接下来,我们将继续创建客户端,并与服务器建立连接,实现实时聊天功能。

构建客户端

在本节中,我们将创建简单的 HTML 页面,并使用 JavaScript 来实现 WebSocket 连接,使用户能够在网页上与服务器进行实时通讯。

1. 创建 HTML 页面

首先,创建一个简单的 HTML 页面,用于显示聊天信息和接收用户输入。

<!DOCTYPE html>
<html>
<head><title>WebSocket Chat</title>
</head>
<body><input type="text" id="messageInput" /><button onclick="sendMessage()">Send</button><ul id="chatMessages"></ul><script>var socket = new WebSocket("ws://localhost:8080/ws");socket.onmessage = function(event) {var message = JSON.parse(event.data);var chat = document.getElementById("chatMessages");var messageNode = document.createElement("li");messageNode.appendChild(document.createTextNode(message.username + ": " + message.message));chat.appendChild(messageNode);};function sendMessage() {var messageInput = document.getElementById("messageInput");var message = messageInput.value;var username = prompt("Enter your username:");var email = prompt("Enter your email:");var data = {email: email,username: username,message: message};socket.send(JSON.stringify(data));}</script>
</body>
</html>

2. JavaScript 连接 WebSocket

JavaScript 部分的代码用于连接服务器的 WebSocket 并处理消息的发送和接收。当用户在输入框中输入消息并点击发送时,消息将通过 WebSocket 发送到服务器,并显示在聊天界面中。
在本节中,我们创建了简单的 HTML 页面和 JavaScript 代码,建立了与服务器的 WebSocket 连接。用户现在能够在网页上输入消息,并实时地与服务器进行通讯。

实现进阶功能

在本节中,我们将介绍如何实现进阶功能,例如私聊和其他增强功能,为聊天工具增加更多交互性和用户友好性。

消息记录:实现消息记录和历史消息查看

实现消息记录和历史消息查看功能需要在服务器端维护消息记录,并在客户端请求时向客户端提供历史消息。以下是一个简单的示例,演示如何在 Golang WebSocket 服务器端维护消息记录并提供历史消息查看功能:

维护消息记录

var history []Message
var mutex sync.Mutex

提供历史消息查看

func handleMessages() {for {msg := <-broadcastmutex.Lock()history = append(history, msg)mutex.Unlock()for client := range clients {err := client.WriteJSON(msg)if err != nil {log.Printf("error: %v", err)client.Close()mutex.Lock()delete(clients, client)mutex.Unlock()}}}
}

在上述代码中,使用 sync.Mutex 来确保对历史消息的安全访问。当新客户端连接时,它会首先收到历史消息。在接收到新消息时,它将更新历史消息,并将其发送给所有连接的客户端。

在线用户列表

要实现在线用户列表功能,可以通过跟踪连接到服务器的客户端来维护当前在线用户的列表。在 Golang 服务器端,可以维护一个用户列表,每当新的客户端连接或断开连接时更新这个列表。然后,可以将在线用户列表信息通过 WebSocket 发送给所有客户端,以便在客户端界面上显示当前在线用户。
以下是一个简单的示例,演示了如何在 Golang WebSocket 服务器中维护在线用户列表并向客户端发送在线用户信息:

var onlineUsers []string
var clients = make(map[*websocket.Conn]string)func handleConnections(w http.ResponseWriter, r *http.Request) {...var username stringif name := r.URL.Query().Get("username"); name != "" {username = nameclients[ws] = username // 将连接与用户名关联mutex.Lock()onlineUsers = append(onlineUsers, username)sendOnlineUsersList()mutex.Unlock()} else {log.Printf("Username not provided.")return}for {var msg Messageerr := ws.ReadJSON(&msg)if err != nil {log.Printf("error: %v", err)mutex.Lock()delete(clients, ws)onlineUsers = removeUser(onlineUsers, username)sendOnlineUsersList()mutex.Unlock()break}...}...
}func sendOnlineUsersList() {userListMessage := Message{Type:  "userlist",Users: onlineUsers,}for client := range clients {err := client.WriteJSON(userListMessage)if err != nil {log.Printf("error: %v", err)client.Close()mutex.Lock()delete(clients, client)mutex.Unlock()}}
}func removeUser(users []string, username string) []string {for i, user := range users {if user == username {return append(users[:i], users[i+1:]...)}}return users
}

这段代码是一个简化的示例,它展示了在 Golang 中维护在线用户列表和向客户端发送在线用户信息的基本逻辑。在客户端,可以通过 JavaScript 接收并处理这些在线用户列表信息,然后在界面上显示当前在线的用户列表。

私聊功能

要实现私聊功能,我们需要对消息进行处理,识别私聊的目标用户,并将消息发送给特定用户而非广播给所有用户。

type Message struct {Username string   `json:"username"`Message  string   `json:"message"`Type     string   `json:"type"`ToUser   string   `json:"toUser"`Users    []string `json:"users"`
}func handleConnections(w http.ResponseWriter, r *http.Request) {...// 在线用户逻辑不变for {...if msg.Type == "message" {if msg.Username != "" && msg.Message != "" {if msg.ToUser != "" {sendMessageToUser(msg)} else {broadcast <- msg}}}}...
}func sendMessageToUser(msg Message) {for client, user := range clients {if user == msg.ToUser || user == msg.Username {err := client.WriteJSON(msg)if err != nil {log.Printf("error: %v", err)client.Close()mutex.Lock()delete(clients, client)onlineUsers = removeUser(onlineUsers, user)mutex.Unlock()}}}
}

样式美化

在页面上显示在线用户列表和历史消息需要对前端代码做一些调整。可以使用 JavaScript 动态更新页面,将接收到的在线用户列表和历史消息添加到页面上的列表中。以下是一个简单的示例,展示如何更新页面以显示在线用户列表和历史消息:

HTML 结构

<input type="text" id="usernameInput" placeholder="Enter your username" />
<button onclick="connectWebSocket()">Connect</button>
<div id="chatContainer"><div><input type="text" id="messageInput" placeholder="Type a message..." disabled /><button onclick="sendMessage()" disabled>Send</button><div id="chatMessages"></div></div><div><h3>Online Users</h3><ul id="onlineUsers"></ul></div>
</div>

CSS 样式

body {font-family: Arial, sans-serif;margin: 20px;
}#chatContainer {display: flex;
}#chatMessages,
#onlineUsers {border: 1px solid #ccc;border-radius: 5px;padding: 10px;width: 300px;height: 300px;overflow-y: scroll;
}#chatMessages {margin-right: 10px;
}ul {list-style: none;padding: 0;
}li {margin-bottom: 5px;
}input[type="text"] {padding: 8px;margin-bottom: 10px;
}button {padding: 8px;
}.messageContainer {margin-bottom: 10px;
}.username {font-weight: bold;color: #333;
}.messageText {margin-left: 10px;
}.onlineUser {cursor: pointer;
}

Javascript 部分:

var socket;
var username = '';function connectWebSocket() {username = document.getElementById("usernameInput").value;if (username) {socket = new WebSocket("ws://localhost:8080/ws?username=" + username);socket.onopen = function (event) {document.getElementById("messageInput").disabled = false;document.querySelector('button[onclick="sendMessage()"]').disabled = false;};socket.onmessage = function (event) {var data = JSON.parse(event.data);var chat = document.getElementById("chatMessages");var onlineUsersList = document.getElementById("onlineUsers");if (data.type === "userlist") {onlineUsersList.innerHTML = '';data.users.forEach(function (user) {var userNode = document.createElement("li");userNode.classList.add("onlineUser");userNode.appendChild(document.createTextNode(user));userNode.onclick = function () {document.getElementById("messageInput").value = `@${user} `;};onlineUsersList.appendChild(userNode);});} else if (data.type === "message") {var messageNode = document.createElement("div");messageNode.classList.add("messageContainer");var usernameNode = document.createElement("span");usernameNode.classList.add("username");usernameNode.appendChild(document.createTextNode(data.username + ": "));messageNode.appendChild(usernameNode);var messageTextNode = document.createElement("span");messageTextNode.classList.add("messageText");messageTextNode.appendChild(document.createTextNode(data.message));messageNode.appendChild(messageTextNode);chat.appendChild(messageNode);}};} else {alert('Please enter a username to connect.');}
}function sendMessage() {var messageInput = document.getElementById("messageInput");var message = messageInput.value;if (message) {var toUser = extractToUser(message);var data = {type: "message",username: username,message: message,toUser: toUser};socket.send(JSON.stringify(data));messageInput.value = '';} else {alert('Please type a message to send.');}
}function extractToUser(message) {var atIndex = message.indexOf('@');if (atIndex !== -1) {var spaceIndex = message.indexOf(' ', atIndex);if (spaceIndex !== -1) {return message.substring(atIndex + 1, spaceIndex);} else {return message.substring(atIndex + 1);}}return "";
}

部署与测试

在这一部分,我们将介绍如何部署服务器和进行测试,确保聊天工具能够在实际环境中正常运行。

1. 部署服务器

将 Golang 代码部署到您选择的服务器上。确保服务器上已安装 Golang 运行环境,并启动服务,监听指定的端口(在本例中是 :8080)。

go run main.go

或者使用编译后的可执行文件:

go build main.go
./main

2. 客户端测试

在浏览器中打开聊天工具的前端页面。输入用户名,然后发送消息,确认消息能够发送并在界面上展示。
在这里插入图片描述
输入用户名点击connect,在online users列表里会展示在线用户。
在这里插入图片描述
输入消息会在聊天记录里展示。为了演示私聊功能,我们再创建一个用户加入聊天。
在这里插入图片描述
此时在小明聊天页面,点击online users里的小王展开私聊(聊天框里会出现@小王)

在这里插入图片描述

总结

在本教程中,我们详细介绍了如何使用 Golang 和 WebSocket 技术构建一个简单但功能完善的实时聊天工具。我们逐步展示了构建服务器、客户端以及一些进阶功能的基本方法。
我们学到了:

WebSocket的应用:我们深入了解了 WebSocket 技术,并利用它在 Golang 服务器端和客户端之间建立实时通讯。

  1. 服务器端构建:使用 Golang 和 Gorilla WebSocket 库构建了服务器端,处理连接、消息传递和在线用户列表。
  2. 客户端构建:创建了简单的 HTML 页面和 JavaScript 代码,实现了与服务器的 WebSocket 连接和消息的发送接收。
  3. 进阶功能:介绍了私聊、样式和格式、消息记录和历史消息查看、在线用户列表等进阶功能的实现方法。
  4. 部署与测试:指导了服务器端的部署以及客户端功能的测试方法,确保聊天工具能够在实际环境中稳定运行。

这个简单的聊天工具只是一个开始,我们可以根据需求和创意进一步扩展和优化功能,比如加强安全性、添加文件传输功能等。希望这个教程能够帮助您开始使用 Golang 和 WebSocket 构建实时应用,为您未来的项目打下基础。

项目源码

点击下载

这篇关于Golang实现一个聊天工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877735

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

利用Frp实现内网穿透(docker实现)

文章目录 1、WSL子系统配置2、腾讯云服务器安装frps2.1、创建配置文件2.2 、创建frps容器 3、WSL2子系统Centos服务器安装frpc服务3.1、安装docker3.2、创建配置文件3.3 、创建frpc容器 4、WSL2子系统Centos服务器安装nginx服务 环境配置:一台公网服务器(腾讯云)、一台笔记本电脑、WSL子系统涉及知识:docker、Frp

基于 Java 实现的智能客服聊天工具模拟场景

服务端代码 import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class Serv