欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Golang編寫一個聊天工具

 更新時間:2023年11月09日 14:23:00   作者:surzia  
這篇文章主要為大家詳細介紹了如何使用?Golang?構建一個簡單但功能完善的聊天工具,利用?WebSocket?技術實現即時通訊的功能,需要的小伙伴可以參考下

簡介

聊天工具作為實時通訊的必要工具,在現代互聯網世界中扮演著重要的角色。本博客將指導如何使用 Golang 構建一個簡單但功能完善的聊天工具,利用 WebSocket 技術實現即時通訊的功能。

為什么選擇 Golang

Golang 是一種高效、簡潔且并發(fā)性強的編程語言。其強大的并發(fā)模型和高效的性能使其成為構建高負載實時應用的理想選擇。在本教程中,我們將利用 Golang 的優(yōu)勢來創(chuàng)建一個輕量級但高效的聊天工具。

目標

本教程旨在演示如何使用 Golang 和 WebSocket 技術構建一個簡單的聊天工具。我們將詳細介紹服務器端和客戶端的實現過程,從而能夠了解聊天工具的基本結構和實現原理。

技術棧

在本教程中,我們將詳細介紹 WebSocket 技術,這是構建實時通訊應用的核心組件。同時,我們還將使用 Golang、HTML/CSS/JavaScript 和 Gorilla WebSocket 庫來構建一個簡單的聊天工具。

WebSocket

WebSocket 是一種在單個 TCP 連接上提供全雙工通信的網絡通信協議。它允許客戶端和服務器之間進行實時、雙向的通訊,從而實現了實時更新、即時通訊等功能。

WebSocket 的特點包括

  • 全雙工通信:客戶端和服務器可以同時發(fā)送和接收數據。
  • 實時性:實時的雙向通信,適用于即時聊天、實時數據更新等場景。
  • 少量數據傳輸:相較于傳統 HTTP 請求,WebSocket 傳輸的數據包含更少的開銷,因為它不需要在每次通訊時都發(fā)送頭部信息。

WebSocket 的工作原理

  • 握手階段:客戶端發(fā)起 HTTP 請求,請求升級為 WebSocket 協議。
  • 建立連接:服務端接受請求,升級為 WebSocket 連接。
  • 雙向通信:建立連接后,客戶端和服務端可以相互發(fā)送消息。

在本教程中,我們將使用 WebSocket 技術來建立客戶端與服務器之間的連接,以實現實時聊天的功能。

其他技術

除了 WebSocket,我們還將使用以下技術來構建聊天工具:

  • Golang:作為后端語言,處理 WebSocket 連接,消息傳遞和處理。
  • HTML/CSS/JavaScript:創(chuàng)建簡單的客戶端界面,允許用戶進行聊天。
  • Gorilla WebSocket 庫:一個 Golang 的 WebSocket 庫,提供了一些功能和工具,簡化了使用 WebSocket 的過程。

構建服務器

在本節(jié)中,我們將開始構建聊天工具的服務器端,使用 Golang 和 Gorilla WebSocket 庫來處理客戶端的連接和消息傳遞。

設置基本結構

首先,我們需要創(chuàng)建 Golang 項目結構,確保安裝了 Gorilla WebSocket 庫。在項目中創(chuàng)建一個 main.go 文件,并導入 WebSocket 庫。

package main

import (
	"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"`
}

處理連接

接下來,我們將創(chuàng)建一個函數來處理客戶端的連接。這個函數將升級 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] = true

	for {
		var msg Message
		err := ws.ReadJSON(&msg)
		if err != nil {
			log.Printf("error: %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("error: %v", err)
				client.Close()
				delete(clients, client)
			}
		}
	}
}

設置服務器

最后,我們需要設置服務器并啟動監(jiān)聽。

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

在本節(jié)中,我們建立了一個基本的服務器結構,使用 Golang 和 Gorilla WebSocket 庫處理 WebSocket 連接和消息傳遞。接下來,我們將繼續(xù)創(chuàng)建客戶端,并與服務器建立連接,實現實時聊天功能。

構建客戶端

在本節(jié)中,我們將創(chuàng)建簡單的 HTML 頁面,并使用 JavaScript 來實現 WebSocket 連接,使用戶能夠在網頁上與服務器進行實時通訊。

創(chuàng)建 HTML 頁面

首先,創(chuàng)建一個簡單的 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>

JavaScript 連接 WebSocket

JavaScript 部分的代碼用于連接服務器的 WebSocket 并處理消息的發(fā)送和接收。當用戶在輸入框中輸入消息并點擊發(fā)送時,消息將通過 WebSocket 發(fā)送到服務器,并顯示在聊天界面中。

在本節(jié)中,我們創(chuàng)建了簡單的 HTML 頁面和 JavaScript 代碼,建立了與服務器的 WebSocket 連接。用戶現在能夠在網頁上輸入消息,并實時地與服務器進行通訊。

實現進階功能

在本節(jié)中,我們將介紹如何實現進階功能,例如私聊和其他增強功能,為聊天工具增加更多交互性和用戶友好性。

消息記錄:實現消息記錄和歷史消息查看

實現消息記錄和歷史消息查看功能需要在服務器端維護消息記錄,并在客戶端請求時向客戶端提供歷史消息。以下是一個簡單的示例,演示如何在 Golang WebSocket 服務器端維護消息記錄并提供歷史消息查看功能:

維護消息記錄

var history []Message
var mutex sync.Mutex

提供歷史消息查看

func handleMessages() {
	for {
		msg := <-broadcast

		mutex.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 來確保對歷史消息的安全訪問。當新客戶端連接時,它會首先收到歷史消息。在接收到新消息時,它將更新歷史消息,并將其發(fā)送給所有連接的客戶端。

在線用戶列表

要實現在線用戶列表功能,可以通過跟蹤連接到服務器的客戶端來維護當前在線用戶的列表。在 Golang 服務器端,可以維護一個用戶列表,每當新的客戶端連接或斷開連接時更新這個列表。然后,可以將在線用戶列表信息通過 WebSocket 發(fā)送給所有客戶端,以便在客戶端界面上顯示當前在線用戶。

以下是一個簡單的示例,演示了如何在 Golang WebSocket 服務器中維護在線用戶列表并向客戶端發(fā)送在線用戶信息:

var onlineUsers []string
var clients = make(map[*websocket.Conn]string)

func handleConnections(w http.ResponseWriter, r *http.Request) {
	...

	var username string
	if name := r.URL.Query().Get("username"); name != "" {
		username = name
		clients[ws] = username // 將連接與用戶名關聯
		mutex.Lock()
		onlineUsers = append(onlineUsers, username)
		sendOnlineUsersList()
		mutex.Unlock()
	} else {
		log.Printf("Username not provided.")
		return
	}
        
        for {
		var msg Message
		err := 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 中維護在線用戶列表和向客戶端發(fā)送在線用戶信息的基本邏輯。在客戶端,可以通過 JavaScript 接收并處理這些在線用戶列表信息,然后在界面上顯示當前在線的用戶列表。

私聊功能

要實現私聊功能,我們需要對消息進行處理,識別私聊的目標用戶,并將消息發(fā)送給特定用戶而非廣播給所有用戶。

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 動態(tài)更新頁面,將接收到的在線用戶列表和歷史消息添加到頁面上的列表中。以下是一個簡單的示例,展示如何更新頁面以顯示在線用戶列表和歷史消息:

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 "";
}

部署與測試

在這一部分,我們將介紹如何部署服務器和進行測試,確保聊天工具能夠在實際環(huán)境中正常運行。

部署服務器

將 Golang 代碼部署到您選擇的服務器上。確保服務器上已安裝 Golang 運行環(huán)境,并啟動服務,監(jiān)聽指定的端口(在本例中是 :8080)。

go run main.go

或者使用編譯后的可執(zhí)行文件:

go build main.go
./main

客戶端測試

在瀏覽器中打開聊天工具的前端頁面。輸入用戶名,然后發(fā)送消息,確認消息能夠發(fā)送并在界面上展示。

輸入用戶名點擊connect,在online users列表里會展示在線用戶。

輸入消息會在聊天記錄里展示。為了演示私聊功能,我們再創(chuàng)建一個用戶加入聊天。

此時在小明聊天頁面,點擊online users里的小王展開私聊(聊天框里會出現@小王)

可以看到,在小藍的聊天頁面是看不到兩人的私聊的。

總結

在本教程中,我們詳細介紹了如何使用 Golang 和 WebSocket 技術構建一個簡單但功能完善的實時聊天工具。我們逐步展示了構建服務器、客戶端以及一些進階功能的基本方法。

我們學到了:

  • WebSocket的應用:我們深入了解了 WebSocket 技術,并利用它在 Golang 服務器端和客戶端之間建立實時通訊。
  • 服務器端構建:使用 Golang 和 Gorilla WebSocket 庫構建了服務器端,處理連接、消息傳遞和在線用戶列表。
  • 客戶端構建:創(chuàng)建了簡單的 HTML 頁面和 JavaScript 代碼,實現了與服務器的 WebSocket 連接和消息的發(fā)送接收。
  • 進階功能:介紹了私聊、樣式和格式、消息記錄和歷史消息查看、在線用戶列表等進階功能的實現方法。
  • 部署與測試:指導了服務器端的部署以及客戶端功能的測試方法,確保聊天工具能夠在實際環(huán)境中穩(wěn)定運行。

這個簡單的聊天工具只是一個開始,我們可以根據需求和創(chuàng)意進一步擴展和優(yōu)化功能,比如加強安全性、添加文件傳輸功能等。希望這個教程能夠幫助您開始使用 Golang 和 WebSocket 構建實時應用,為您未來的項目打下基礎。

源碼

本文源碼已經上傳到:Github

以上就是基于Golang編寫一個聊天工具的詳細內容,更多關于Go聊天的資料請關注腳本之家其它相關文章!

相關文章

  • 利用GO語言實現多人聊天室實例教程

    利用GO語言實現多人聊天室實例教程

    聊天室的實現大家應該都遇到過,這篇文章主要給大家介紹了關于利用GO語言實現多人聊天室的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2018-03-03
  • Golang打包go項目部署到linux服務器正確方法

    Golang打包go項目部署到linux服務器正確方法

    這篇文章主要給大家介紹了關于Golang打包go項目部署到linux服務器的正確方法,Go?是一個開源的編程語言,它能讓構造簡單、可靠且高效的軟件變得容易,具有簡潔、快速、安全,并行、有趣、開源,內存管理、v數組安全、編譯迅速的特征,需要的朋友可以參考下
    2023-10-10
  • GO語言求100以內的素數

    GO語言求100以內的素數

    這篇文章主要介紹了GO語言求100以內的素數,主要通過篩選法來實現,涉及GO語言基本的循環(huán)與函數調用方法,需要的朋友可以參考下
    2014-12-12
  • Go設計模式之備忘錄模式圖文詳解

    Go設計模式之備忘錄模式圖文詳解

    備忘錄模式是一種行為設計模式, 允許在不暴露對象實現細節(jié)的情況下保存和恢復對象之前的狀態(tài),本文主要通過一些圖片來給大家介紹一下Go的備忘錄模式,需要的朋友可以參考下
    2023-08-08
  • Go實現MD5加密的三種方法小結

    Go實現MD5加密的三種方法小結

    本文主要介紹了Go實現MD5加密的三種方法小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • 從零封裝Gin框架配置初始化全局變量

    從零封裝Gin框架配置初始化全局變量

    這篇文章主要為大家介紹了從零封裝Gin框架配置初始化全局變量,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • go zero微服務框架logx日志組件剖析

    go zero微服務框架logx日志組件剖析

    這篇文章主要為大家介紹了go zero微服務框架logx日志組件剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • go語法入門any類型的使用場景示例詳解

    go語法入門any類型的使用場景示例詳解

    這篇文章主要為大家介紹了go語法入門any類型的使用場景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • go語言分布式id生成器及分布式鎖介紹

    go語言分布式id生成器及分布式鎖介紹

    這篇文章主要為大家介紹了go語言分布式id生成器及分布式鎖介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Go語言使用釘釘機器人推送消息的實現示例

    Go語言使用釘釘機器人推送消息的實現示例

    本文主要介紹了Go語言使用釘釘機器人推送消息的實現示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論